【问题标题】:How to handle Task Exceptions in GUI?如何在 GUI 中处理任务异常?
【发布时间】:2012-09-01 08:36:41
【问题描述】:

当使用 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)

结束子

【问题讨论】:

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


    【解决方案1】:

    在处理许多其他事情的同时处理并行应用程序中的异常是一项痛苦的任务,需要足够的知识和技能。考虑使用 .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 中的工作原理,并涵盖了一些高级主题,异常处理就是其中之一。

    【讨论】:

    • 我知道这个错误处理问题可以用 Await 很好地解决。但是我也希望有一个健壮的错误处理模式,以便在没有 Await 的情况下使用。我用更好的 cmets 更新了我的代码示例。
    • 有关此问题的更深入讨论,请参阅[如何在没有等待的情况下处理 GUI 中的任务异常? ] (social.msdn.microsoft.com/Forums/en-US/parallelextensions/…)。有关替代解决方案,请参阅 [Task.ContinueWith() 的异常处理包装器] (rizalalmashoor.com/blog/…)
    猜你喜欢
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 2014-06-30
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多