我有一个如下功能(仅保留此示例的相关代码):
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.Run
或Factory.StartNew
< / p>
此外,尝试启动任务并等待它以确保评估结果。但是,当我执行Task.Wait
时,我的用户界面会被屏蔽。
非常感谢任何帮助。
答案 0 :(得分:2)
可能你想要的是
Dim task1 = RefreshCompanyCodesAsync()
这样就没有包装任务了。 RefreshCompanyCodesAsync
已经非阻塞,这很重要,因此您不会冻结用户界面。
你应该避免ContinueWith
。更喜欢等待,因为它会将你编组回UI线程。
我需要在C#中写这个:
var task1 = RefreshCompanyCodesAsync();
await Task.WhenAny(task1); //Wait without throwing.
MessageBox.Show(task1.Status.ToString());