我的理解是,在 Windows 窗体应用程序中,如果 UI 线程抛出异常并且不由用户代码处理,则应用程序将以用户显而易见的方式崩溃。(屏幕上将出现一条消息,指示应用程序已崩溃,或窗口将冻结,或两者兼而有之)
现在考虑以下代码:
try
{
PerformAsyncOperation();
while(!async_op_complete)
{
Application.DoEvents();
}
}
catch
{
Print("exception");
}
我不明白的是,因为 Windows 窗体具有同步上下文,所以在控制离开事件处理程序之前不会执行异步操作(顺便说一下,我不是在谈论 .net 4.5)。一旦发生这种情况,异步代码将在 UI 线程内运行。如果该代码要引发异常,则它不会被围绕异步方法调用的 try-catch 语句捕获,因为在引发异常时控制已经离开了该 try-catch 语句。
但在上述情况下,我们正在循环的事实意味着控制保留在 UI 线程中,而我们在循环中调用 Application.DoEvents() 的事实意味着异步操作在内部“异步”执行用户界面线程。并且由于该循环发生在 try 子句中,因此 async 方法抛出的任何异常都将被相应的 catch 子句捕获。(至少这是我观察到的行为。)
也就是说,
在循环中调用 Application.DoEvents() 以保持 UI 响应,同时等待异步操作完成,然后继续在同一个 UI 线程中做更多工作,这是一个好主意吗?
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()?