我几年前实现的基本 ViewModel 提供了这种扩展方法来运行任务,同时保持 UI 响应*:
protected void Work(Action job)
{
IsBusy = true;
var stackTrace = new StackTrace();
var task = Task.Factory.StartNew(job)
.ContinueWith(failedTask => HandleException(failedTask, stackTrace),
TaskContinuationOptions.OnlyOnFaulted)
.ContinueWith(_ => { IsBusy = false; });
}
void HandleException(Task task, StackTrace stackTrace)
{
Dispatcher.BeginInvoke(
() => { throw new Exception(task.Exception.InnerException.ToString() +
stackTrace); });
}
IsBusy
是从 UI 观察到的用于显示进度条的属性。
背后的想法HandleExceptions
是观察它们,然后将它们扔到 UI 线程中,被方法try/catch
中的块捕获Main()
并记录,然后向用户显示友好的消息并安全地关闭应用程序。传递了 stackTrace,因此日志包含调用者信息。
然而,我最近开始收到关于应用程序崩溃的报告,没有记录,也没有友好的消息,使用这个 Windows 对话框:
查看 Windows 事件日志,我们得到了这个 EventData:
应用程序:xxxxApplication.Loader.exe
框架版本:v4.0.30319
说明:进程因未处理的异常而终止。
异常信息:System.AggregateException
堆栈:在 System.Threading.Tasks.TaskExceptionHolder.Finalize()
我做错了ContinueWith()
什么吗?
任务异常是否有可能以某种方式未被观察到?
*:我知道BackgroundWorker
。这在当时似乎是一个更好的主意,或者有额外的好处。