0

使用 Tasks 解锁 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)

结束子

4

1 回答 1

0

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

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

还可以考虑查看使用任务并行库的异常处理,它为您提供了在使用 TPL 进行并行编程时如何处理异常的良好见解。

Stephen Toub 提出的“异步之禅:最佳性能的最佳实践”还深入探讨了async.Net 4.5 的底层工作原理,并涵盖了一些高级主题,异常处理就是其中之一。

于 2012-09-01T09:04:48.617 回答