gpt4 book ai didi

.net - 将 CancellationToken 作为参数传递给 Task.Run 有什么好处?

转载 作者:行者123 更新时间:2023-12-04 11:33:51 29 4
gpt4 key购买 nike

显然我意识到它使我能够取消任务,但是这段代码无需将 token 传递给 Task.Run 即可达到相同的效果

有什么实际区别?谢谢。

Dim cts As New CancellationTokenSource
Dim ct As CancellationToken = cts.Token
Task.Run(Sub()
For i = 1 To 1000
Debug.WriteLine(i)
ct.ThrowIfCancellationRequested()
Threading.Thread.Sleep(10)
Next
End Sub)

cts.CancelAfter(500)

VS
Dim cts As New CancellationTokenSource
Dim ct As CancellationToken = cts.Token
Task.Run(Sub()
For i = 1 To 1000
Debug.WriteLine(i)
ct.ThrowIfCancellationRequested()
Threading.Thread.Sleep(10)
Next
End Sub, ct)

cts.CancelAfter(500)

最佳答案

API docs for Task.Run(Action, CancellationToken) 有这样的评论:

If cancellation is requested before the task begins execution, the task does not execute. Instead it is set to the Canceled state and throws a TaskCanceledException exception.



因此,在您的场景中,没有任何实际区别,因为您在发出取消之前等待 500 毫秒。在那段时间内,任务被调度,开始执行,并在发出取消之前多次运行循环,表现为从 ct.ThrowIfCancellationRequested() 抛出的异常。 .
Task.Run(Action) 之间的区别和 Task.Run(Action, CancellationToken)您的示例的此修改版本更明显:
Try
Dim cts As New CancellationTokenSource
Dim ct As CancellationToken = cts.Token

cts.Cancel()

Dim task As Task = Task.Run(
Sub()
Console.WriteLine("Started running your code!")
ct.ThrowIfCancellationRequested()
Console.WriteLine("Finished running your code!")
End Sub, ct)

task.Wait()

Catch ex As AggregateException
Console.Error.WriteLine("Caught exception: " & ex.InnerException.Message)
End Try

Console.WriteLine("Done, press Enter to quit.")
Console.ReadLine()

在这种情况下, Task.Run安排任务运行,但还将取消 token 与该任务相关联。当我们调用 task.Wait() ,在线程池执行任务之前,它会检查取消 token 并注意到已在该 token 上发出取消,因此它决定在执行任务之前取消。所以输出是:
Caught exception: A task was canceled.
Done, press Enter to quit.

如果您改为替换: End Sub, ct)End Sub) ,然后线程池不知道取消 token ,因此即使您发出了取消,它也会继续执行任务,然后您的任务代码本身会检查取消。所以输出是:
Started running your code!
Caught exception: The operation was canceled.
Done, press Enter to quit.

(您可以看到,这两种情况下的异常消息也略有不同。)

总之,将取消 token 提供给 Task.Run方法允许线程池本身在线程池有机会执行任务之前知道任务是否被取消。这允许线程池通过甚至不费心开始运行任务来节省时间和资源。

关于.net - 将 CancellationToken 作为参数传递给 Task.Run 有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48312544/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com