0

My understanding is that in a windows forms application if the UI thread throws an exception and it is not handled by user code the application will crash in a manner that is obvious to the user. (A message will appear on the screen indicating that the application has crashed, or the window will freeze, or both)

Now consider the following code:

try
{
     PerformAsyncOperation();
     while(!async_op_complete)
     {
           Application.DoEvents();
     }
}
catch
{
    Print("exception");
}

My undestanding is that because a windows form has a synchronization context, the async operation (and I'm not talking about .net 4.5, by the way) won't be performed until control leaves the event handler procedure. Once that happens the async code will run, inside the UI thread. If that code were to throw an exception then it wouldn't be caught by the try-catch statement surrounding the call to the async method, since control will have already left that try-catch statement by the time the exception is thrown.

But in cases such as the one above, the fact that we are looping means that control remains inside the UI thread, and the fact that we are calling Application.DoEvents() inside the loop means that the async operation is performed "asynchronously" inside the UI thread. And because that loop takes place inside the try clause then any exception thrown by the async method will be caught by the corresponding catch clause. (At least this is the behavior I have observed.)

That said,

  1. Is it ever a good idea to call Application.DoEvents() inside a loop in order to keep the UI responsive while waiting for an async operation to complete before moving on to doing more work inside the same UI thread?

  2. Even if it's not a good idea to call Application.DoEvents() inside a loop, why does the application quietly exit (no window freezes, no error messages) after the catch clause handles the exception thrown by PerformAsyncOperation()?

J Smith
  • 2,375
  • 3
  • 18
  • 36
  • By default, this catch should never catch anything. Whether or not you use a debugger and the Application.SetUnhandledExceptionMode() value matters. It is unclear how you blew your foot off, but that's certainly a common outcome when you use DoEvents. Details [are here.](http://stackoverflow.com/questions/5181777/use-of-application-doevents/5183623#5183623) – Hans Passant Mar 21 '13 at 16:28

1 Answers1

1

1) Is it ever a good idea to call Application.DoEvents() inside a loop in order to keep the UI responsive while waiting for an async operation to complete before moving on to doing more work inside the same UI thread?

Absolutely Not! DoEvents() is evil and will cause you all sorts of problems.

2) Even if it's not a good idea to call Application.DoEvents() inside a loop, why does the application quietly exit (no window freezes, no error messages) after the catch clause handles the exception thrown by PerformAsyncOperation()?

Difficult to say without knowing what PerformAsyncOperation() does. Unless it explicitly uses a new Thread ( or Task ), it will execute synchronously before your loop.

As for the app exit - I can't explain that.

If an uncaught exception is thrown on a worker Thread, the app will show the "stopped working" dialog box and exit.

The only thing I know that has changed is the behaviour when an uncaught exception is thrown from inside a Task. Prior to .NET 4.5, this would cause a fast fail as with a Thread.

If you have installed .NET 4.5 ( even if the app targets 4.0 ) an uncaught exception in a Task is now silently swallowed.

Here's an article that explains the behaviours: MSDN: Task Exception Handling in .NET 4.5

Nick Butler
  • 24,045
  • 4
  • 49
  • 70