取消 Task.Run 个作业
Cancel Task.Run job
我有 async
方法,如下所示。当用户决定停止工作时,我希望有可能 cancel
它。我怎么能在新按钮中做到这一点 CancelUpdate_Click
Private Async Sub btnUpdate_Click(sender As Object, e As EventArgs) Handles btnUpdate.Click
Await DoWorkAsync()
End Sub
Private Function DoWorkAsync() As Task(Of List(Of Vals))
Return _
Task.Run(
Async Function() _
_migrator.PrepareMigration(CInt(Invoke(New Func(Of Integer)(Function() lbNumms.SelectedValue))), CInt(Invoke(New Func(Of Integer)(Function() lbPro.SelectedValue)))))
End Function
Private Sub CancelUpdate_Click(sender As Object, e As EventArgs) Handles CancelUpdate.Click
'Stop DoWorkAsync if running
End Sub
更新:
Private _tokenSource As New CancellationTokenSource()
Private ReadOnly _token = _tokenSource.Token
Private Async Sub btnUpdate_Click(sender As Object, e As EventArgs) Handles btnUpdate.Click
Try
Private ReadOnly _tokenSource As New CancellationTokenSource()
Private ReadOnly _token = _tokenSource.Token
Await DoWorkAsync()
Catch oe As OperationCanceledException
MessageBox.Show("Task has been cancelled")
Finally
_tokenSource.Dispose()
End Try
End Sub
Private Function DoWorkAsync() As Task(Of List(Of Vals))
Return _
Task.Run(
Function()
Dim tokenSource = New CancellationTokenSource()
Dim token = tokenSource.Token
Return _migrator.PrepareMigration(CInt(Invoke(New Func(Of Integer)(Function() lbNumms.SelectedValue))), CInt(Invoke(New Func(Of Integer)(Function() lbProducent.SelectedValue))), _token)
End Function)
End Function
Public Function PrepareMigration(value1 As Integer, value2 As Integer, cancellationToken As CancellationToken) As List(Of Vals))
cancellationToken.ThrowIfCancellationRequested()
MethodA()
cancellationToken.ThrowIfCancellationRequested()
MethodB()
End Function
Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
_tokenSource.Cancel()
End Sub
取消并不是神奇的事情。它必须明确编码。在这种情况下,您的 PrepareMigration
例程需要采用 CancellationToken
参数 并且 需要定期检查该参数的 IsCancellationRequested
属性 已设置为 True
.
这样做的一个捷径是定期调用令牌上的 ThrowIfCancellationRequested
;如果设置了 属性,这将导致 OperationCanceledException
。
如果您的日常工作 return 是 Task
,您可以 return Task.FromCanceled
.
你会得到 CancellationToken
从 CancellationTokenSource
传入。然后取消按钮的事件处理程序将在源上调用 Cancel
以发出已发出令牌的信号。
例如,如果您的处理涉及多个步骤,可能会像这样工作:
'Include other parameters as appropriate.
Sub PrepareMigration(ByVal token As CancellationToken)
DoStep1()
token.ThrowIfCancellationRequested()
DoStep2()
'...
token.ThrowIfCancellationRequested()
DoStepn()
End Sub
或者,如果您要处理一组项目,可能看起来像这样:
Sub PrepareMigration(ByVal token As CancellationToken)
For Each item In itemsToProcess
token.ThrowIfCancellationRequested()
DoTheItem(item)
Next
End Sub
根据需要混合搭配。如果在特定步骤中调用的例程特别是 long-running,则该例程本身可能需要是 cancellation-aware.
最终,检查的位置取决于计算步骤的详细信息(包括可能的“快速”与“慢速”步骤)以及您要对用户必须等待多长时间设置的限制请求取消生效。
我有 async
方法,如下所示。当用户决定停止工作时,我希望有可能 cancel
它。我怎么能在新按钮中做到这一点 CancelUpdate_Click
Private Async Sub btnUpdate_Click(sender As Object, e As EventArgs) Handles btnUpdate.Click
Await DoWorkAsync()
End Sub
Private Function DoWorkAsync() As Task(Of List(Of Vals))
Return _
Task.Run(
Async Function() _
_migrator.PrepareMigration(CInt(Invoke(New Func(Of Integer)(Function() lbNumms.SelectedValue))), CInt(Invoke(New Func(Of Integer)(Function() lbPro.SelectedValue)))))
End Function
Private Sub CancelUpdate_Click(sender As Object, e As EventArgs) Handles CancelUpdate.Click
'Stop DoWorkAsync if running
End Sub
更新:
Private _tokenSource As New CancellationTokenSource()
Private ReadOnly _token = _tokenSource.Token
Private Async Sub btnUpdate_Click(sender As Object, e As EventArgs) Handles btnUpdate.Click
Try
Private ReadOnly _tokenSource As New CancellationTokenSource()
Private ReadOnly _token = _tokenSource.Token
Await DoWorkAsync()
Catch oe As OperationCanceledException
MessageBox.Show("Task has been cancelled")
Finally
_tokenSource.Dispose()
End Try
End Sub
Private Function DoWorkAsync() As Task(Of List(Of Vals))
Return _
Task.Run(
Function()
Dim tokenSource = New CancellationTokenSource()
Dim token = tokenSource.Token
Return _migrator.PrepareMigration(CInt(Invoke(New Func(Of Integer)(Function() lbNumms.SelectedValue))), CInt(Invoke(New Func(Of Integer)(Function() lbProducent.SelectedValue))), _token)
End Function)
End Function
Public Function PrepareMigration(value1 As Integer, value2 As Integer, cancellationToken As CancellationToken) As List(Of Vals))
cancellationToken.ThrowIfCancellationRequested()
MethodA()
cancellationToken.ThrowIfCancellationRequested()
MethodB()
End Function
Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
_tokenSource.Cancel()
End Sub
取消并不是神奇的事情。它必须明确编码。在这种情况下,您的 PrepareMigration
例程需要采用 CancellationToken
参数 并且 需要定期检查该参数的 IsCancellationRequested
属性 已设置为 True
.
这样做的一个捷径是定期调用令牌上的 ThrowIfCancellationRequested
;如果设置了 属性,这将导致 OperationCanceledException
。
如果您的日常工作 return 是 Task
,您可以 return Task.FromCanceled
.
你会得到 CancellationToken
从 CancellationTokenSource
传入。然后取消按钮的事件处理程序将在源上调用 Cancel
以发出已发出令牌的信号。
例如,如果您的处理涉及多个步骤,可能会像这样工作:
'Include other parameters as appropriate.
Sub PrepareMigration(ByVal token As CancellationToken)
DoStep1()
token.ThrowIfCancellationRequested()
DoStep2()
'...
token.ThrowIfCancellationRequested()
DoStepn()
End Sub
或者,如果您要处理一组项目,可能看起来像这样:
Sub PrepareMigration(ByVal token As CancellationToken)
For Each item In itemsToProcess
token.ThrowIfCancellationRequested()
DoTheItem(item)
Next
End Sub
根据需要混合搭配。如果在特定步骤中调用的例程特别是 long-running,则该例程本身可能需要是 cancellation-aware.
最终,检查的位置取决于计算步骤的详细信息(包括可能的“快速”与“慢速”步骤)以及您要对用户必须等待多长时间设置的限制请求取消生效。