如何在GUI中处理任务异常?

时间:2012-09-01 08:36:42

标签: .net vb.net exception-handling task-parallel-library

使用“任务”取消阻止UI并使用Aync / Await时,建议的处理错误的方法是什么?

我通常希望通过更新UI并处理全局错误处理程序(如Application_DispatcherUnhandledException)中的意外错误(日志异常,通知用户和关闭应用程序)来处理预期错误。

我正在使用以下看起来很难看的方法。

Private Sub _showAsyncButton_Click(sender As Object, e As RoutedEventArgs) Handles _showAsyncButton.Click
Dim task = New WebClient().DownloadStringTaskAsync("http://www.microsoft.com")
'Dim task = New WebClient().DownloadStringTaskAsync("forcing error in async I/O")
task.ContinueWith(
    Sub()
        _resultField.Text = task.Result
        'Throw New ApplicationException("forcing error in End method")
    End Sub, Nothing, Nothing, TaskScheduler.FromCurrentSynchronizationContext
    ).ContinueWith(
        Sub(a)
            Select Case True
                Case TypeOf (a.Exception.GetBaseException) Is WebException AndAlso CType(a.Exception.GetBaseException, WebException).Status = WebExceptionStatus.NameResolutionFailure
                    'Handle expected error
                    Dispatcher.Invoke(Sub() MessageBox.Show("Cannot access web site. Please try again later"))
                Case Else
                    'Rethrow unexpected error in global error handler
                    Dispatcher.BeginInvoke(Sub() ExceptionDispatchInfo.Capture(a.Exception).Throw())
                    'ExceptionDispatchInfo.Capture(aex).Throw() 'Does not work 
            End Select
        End Sub, TaskContinuationOptions.OnlyOnFaulted)

End Sub

1 个答案:

答案 0 :(得分:0)

处理并行应用程序中的异常以及处理许多其他内容是一项痛苦的任务,需要足够的知识和技能。考虑使用.Net 4.5中引入的async-await关键字重写上述代码,然后它允许您以与在同步编程模型中相同的方式处理异常。当然,在某些情况下async-await不够用,您需要直接使用TPL API。

然后你可以使用.Net反编译器(即.Net Reflector)来查看编译器代表你做了多少工作,它也是一个非常宝贵的学习源。

另外,请考虑查看Exception Handling with the Task Parallel Library,它为您提供了在使用TPL进行并行编程时如何处理异常的良好见解。

Stephen Toub提出的“The zen of async: Best practices for best performance”也深入研究了async在.Net 4.5中的工作原理,它涵盖了一些高级主题,其中异常处理就是其中之一。