.NET 如何定义异步任务回调

.NET How to define an Async task Callback

我正在将我的代码从 BackgroundWorker 更新到 Tasks,运行 遇到了问题。我想模仿 BackgroundWorker 的功能,当 DoWork() 线程完成时,BackgroundWorker 调用 DoWorkCompleted() 函数。这是我目前拥有的:

Private Sub btn_Start_Click(sender, e) Handles btn_Start.Click
  btn_Stop.IsEnabled = True
  btn_Start.IsEnabled = False
  _cts = New CancellationTokenSource()
  Dim theWork As Task = Worker.Start(_cts.Token)
  theWork.ContinueWith(AddressOf OnWorkCompleted)
End Sub

Private Sub OnWorkCompleted()
  btn_Stop.IsEnabled = False
  btn_Start.IsEnabled = True
End Sub

Private Sub btn_Stop_Click(sender, e) Handles btn_Stop.Click
  _cts.Cancel()
End Sub

然后在另一个文件 Worker.vb 中,我有以下内容:

Private Shared _cts As CancellationToken

Public Shared Function Start(token As CancellationToken) As Task
  Try
    _cts = token
    Return Task.Run(AddressOf Process, token)
  Catch ex As TaskCanceledException
    MessageBox.Show("Task cancelled")
    Return Task.CompletedTask
  End Try
End Function

Private Shared Async Sub Process()
  Try
    Log.Information("0")
    Await Task.Delay(1000, _cts)
    Log.Information("1")
    Await Task.Delay(1000, _cts)
    Log.Information("2")
    Await Task.Delay(1000, _cts)
    Log.Information("3")
    Await Task.Delay(1000, _cts)
    Log.Information("4")
    Await Task.Delay(1000, _cts)
  Catch ex As OperationCanceledException
    MessageBox.Show("cancelled operation")
  End Try
End Sub

差不多,我想要用这段代码发生的事情是模仿当我将它迁移过来时完整代码会发生什么:在用户点击开始后,一个长时间的操作在一个单独的线程上运行并且 UI 仍然有响应。如果用户在任何时候单击停止,任务将结束并调用 OnWorkCompleted 函数。会发生什么情况,是立即调用 OnWorkCompleted() 而不是在单击“停止”时调用。

一般来说,您应该 avoid Async Sub:

Private Shared Async Function Process() As Task

此外,使用 Await 而不是 ContinueWith:

Private Async Sub btn_Start_Click(sender, e) Handles btn_Start.Click
  btn_Stop.IsEnabled = True
  btn_Start.IsEnabled = False
  _cts = New CancellationTokenSource()
  Try
    Await Worker.Start(_cts.Token)
  Finally
    OnWorkCompleted()
  End Try
End Sub

您可能会发现我关于 replacing BackgroundWorker with Task.Run 的博客 post 系列对您有所帮助。