如何停止/取消处理功能的任务或找到更好的方法来执行此操作?

Mea*_*000 3 vb.net delegates task-parallel-library

我有 ...

Private Sub TestTask()
    Debug.Write("Running")

    For i As Integer = 0 To 60
        Debug.Write(".")
        System.Threading.Thread.Sleep(1000)
    Next

    Debug.WriteLine("Finished")
End Sub
Run Code Online (Sandbox Code Playgroud)

....

Dim cts As New CancellationTokenSource
Dim oToken As CancellationToken = cts.Token

'Create HelperTask to wait for cancellation request
Dim oHelperTask As Task = Task.Factory.StartNew(Function()

        'Create Task to invoke function
        Dim oTask As Task = Task.Factory.StartNew(Function()
            Return outerFunction.Invoke
        End Function, oToken)

        ' wait for cancellation token if Task is not complete
        While oTask.Status = TaskStatus.Running
            Thread.Sleep(200)
            If oToken.IsCancellationRequested Then
                oToken.ThrowIfCancellationRequested()
                Return Nothing
            End If
        End While

        Return oTask.Result

End Function, oToken)


cts.cancel()
Run Code Online (Sandbox Code Playgroud)

但是在 Visual Sudio 上的调试窗口中,我的 TestTask() 继续运行......请任何人启发我。谢谢

Pan*_*vos 5

CancellationToken 的全部意义在于,实际的工作人员 lambda(或函数)应该检查它以查看它是否应该停止。在您的情况下,TestTask 必须有权访问令牌并在每次迭代后检查它。多个辅助任务、任务状态检查或取消请求检查都不是必要的。

有关任务取消的 MSDN 文章展示了 lambda 唯一需要的就是检查令牌,仅此而已。

在您的情况下,TestTask 可以使用如下简单的代码来响应取消:

Sub Main()
    Dim cts As New CancellationTokenSource
    Dim token = cts.Token

    Task.Factory.StartNew(Sub() TestTask(token), token)

    Thread.Sleep(3000)
    cts.Cancel()
    Console.ReadKey()
End Sub



Private Sub TestTask(token As CancellationToken)
    Console.Write("Running")

    For i As Integer = 0 To 60

        token.ThrowIfCancellationRequested()

        Console.Write(".")
        Thread.Sleep(1000)
    Next

    Console.WriteLine("Finished")
End Sub
Run Code Online (Sandbox Code Playgroud)

唯一需要的是将令牌传递给 TestTask 并像这样启动它:

        Task.Factory.StartNew(Sub() TestTask(token), token)
Run Code Online (Sandbox Code Playgroud)