Technical Journal

Programming, software technologies, operating systems, IT

.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 );

}

July 30, 2007 Posted by andocs | Windows | | No Comments Yet