Task.Run - 处理异常

时间:2016-05-26 19:20:31

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

我有一个如下功能(仅保留此示例的相关代码):

Public Async Function RefreshCompanyCodesAsync() As Task(Of Boolean)
   For ctr=1 to 2000
      Await Task.Delay(1000).ConfigureAwait(False)
      If ctr=5 Then Throw New ApplicationException("Why 5?") 
   Next
   return true
End Function 

正如您所看到的,我在ctr = 5时生成异常只是为了检查在UI中如何处理异常。

然后我在按钮内点击Async事件:

Dim task1 = Task.Run(Sub()
                          RefreshCompanyCodesAsync()
                     End Sub)
Dim cTask = task1.ContinueWith(Sub(antecedent)
                                           If task1.Status = TaskStatus.RanToCompletion Then
                                               MsgBox("All done")
                                           ElseIf task1.Status = TaskStatus.Faulted Then
                                               MsgBox(task1.Exception.GetBaseException().Message)
                                           End If
                                       End Sub)

任务运行完成而不是出现故障。我猜这是因为包装器任务运行完成而不是抛出异常的原始任务。但是,我不确定如何进入原始任务并处理异常。

我尝试了Await

    Try
        Await RefreshCompanyCodesAsync()
    Catch ax As AggregateException
        MsgBox(ax.Message)
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try

此处遇到异常,但问题是我需要并行启动多个功能,其中RefreshCompanyCodesAsync只是其中之一。要做到这一点,我相信通过Task.Run启动这些功能将是最好的选择。

在我的情况下,worker函数的实际功能涉及广泛的数据库和HttpClient活动,在此期间,UI响应能力促使我进入Task.RunFactory.StartNew < / p>

此外,尝试启动任务并等待它以确保评估结果。但是,当我执行Task.Wait时,我的用户界面会被屏蔽。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

可能你想要的是

Dim task1 = RefreshCompanyCodesAsync()

这样就没有包装任务了。 RefreshCompanyCodesAsync已经非阻塞,这很重要,因此您不会冻结用户界面。

你应该避免ContinueWith。更喜欢等待,因为它会将你编组回UI线程。

我需要在C#中写这个:

var task1 = RefreshCompanyCodesAsync();
await Task.WhenAny(task1); //Wait without throwing.
MessageBox.Show(task1.Status.ToString());