2

我有 ...

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

……

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()

但是在我的 Visual sudio 调试窗口中,我的 TestTask() 继续运行.....请任何人赐教。谢谢

4

2 回答 2

4

CancellationToken 的全部意义在于,实际的 worker 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

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

        Task.Factory.StartNew(Sub() TestTask(token), token)
于 2012-06-01T07:14:26.833 回答
3

您不想要/不需要 2 个任务 - 这是合作取消,因此您希望在调用取消时结束的每个任务都需要包含 ThrowIfCancellationRequested (或者它应该处理取消)。故意没有 Thread.Abort 类型的行为/语义,这都是合作的。

于 2012-05-31T15:06:36.843 回答