.NET NumericUpDown crash workaround
I encountered the following problem when trying to handle a NumericUpDown_ValueChanged event :
In the event handler, the code was very similar to this template :
if( someVal > numericUpDown.Minimum && someVal < numericUpDown.Maximum )
{
// do something here
}
else
{
MessageBox.Show( “Some message” );
}
When the user holds the mouse pressed on one of the control arrows and the MessageBox is to be shown, I get an exception that is more than unexpected.
Here is the complete stack trace :
System.Transactions Critical: 0 : <TraceRecord xmlns=”http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord”
Severity=”Critical”>
<TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier>
<Description>Unhandled exception</Description>
<AppDomain>YOUR_PROJECT_NAME.vshost.exe</AppDomain><Exception>
<ExceptionType>System.NullReferenceException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>Object reference not set to an instance of an object.</Message>
<StackTrace> at System.Windows.Forms.UpDownBase.UpDownButtons.TimerHandler(Object source, EventArgs args)
at System.Windows.Forms.Timer.OnTick(EventArgs e)
at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at
… your line of code …
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()</StackTrace><ExceptionString>System.NullReferenceException: Object reference not set to an instance of an object.
at System.Windows.Forms.UpDownBase.UpDownButtons.TimerHandler(Object source, EventArgs args)
at System.Windows.Forms.Timer.OnTick(EventArgs e)
at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at
… your line of code …
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()</ExceptionString></Exception></TraceRecord>
A first chance exception of type ‘System.Threading.ThreadAbortException’ occurred in mscorlib.dll
As I was to find out digging some Microsoft forums, this is a known, documented issue of the
Microsoft .NET framework. ( https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=251486&wa=wsignin1.0 ).
The workaround is available on this forum and it was of real help to me :
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1554539&SiteID=1.
Basically, “the control does not expect to get a message while it is executing an event handler. The workaround delays your response and lets the control finish its event handling. “
This is a sample( skeleton ) of my code, that uses a delegate instead of the MethodInvoker on the Microsoft forum example :
private delegate void CallMethodParam2( double x, bool y );
private void NumericUpDown_ValueChanged(object sender, EventArgs e)
{
if ( (someVal >= numericUpDown.Minimum ) && ( someVal <= numericUpDown.Maximum ) )
{
// some code
}
else
{// Cancel changes
this.ShowError( someVal );}
}
private void ShowError( double someVal )
{
bool bLess = true;
double val = 0;
if ( someVal<= numericUpDown.Minimum )
{bLess = true;
val = numericUpDown.Minimum ;
}
else if ( someVal >= numericUpDown.Maximum)
{bLess = false;
val = numericUpDown.Maximum;
}
this.BeginInvoke( new CallMethodParam2( this.ShowError ), new object[ ] { val, bLess } );
}
private void ShowError( double dist, bool bLess )
{
string text = “Distance “+ ( ( bLess ) ? “less” : “greater” ) + ” than ” + dist.ToString( ) +” not allowed!”;
MessageBox.Show( text, “Error”, MessageBoxButtons.OK, MessageBoxIcon.Error );
}
-
Archives
- May 2009 (1)
- April 2009 (4)
- February 2008 (1)
- November 2007 (1)
- August 2007 (1)
- July 2007 (2)
- June 2007 (2)
- May 2007 (1)
-
Categories
-
RSS
Entries RSS
Comments RSS
