We all know that Task.Run
the method can be passed a CancellationToken
, for cancellation. But how many people really go to find out about when to call CancellationSource.Cancel
time method, Task
whether it was canceled
We do an experiment
public static async void Foo()
{
var source = new CancellationTokenSource();
Task.Run(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(5));
Console.WriteLine("task 运行结束");
}, source.Token);
await Task.Delay(TimeSpan.FromSeconds(3));
source.Cancel();
Console.WriteLine("取消任务");
}
Create the above program that allows a Task output "task to run over" after running five seconds, but were canceled after 3 seconds.
Surprisingly, even the successful implementation of the task is completed.
To further confirm the results, we add a follow-up mission, before the end of the state to view the next task
public static async void Foo()
{
var source = new CancellationTokenSource();
Task.Run(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(5));
Console.WriteLine("task 运行结束");
}, source.Token).ContinueWith(task => Console.WriteLine(task.Status));
await Task.Delay(TimeSpan.FromSeconds(3));
source.Cancel();
Console.WriteLine("取消任务");
}
As a result RanToCompletion
instead Canceled
, indicating that no task is canceled
If you do not cancel before we wait for three seconds, and add tasks to start running log
public static async void Foo()
{
var source = new CancellationTokenSource();
Task.Run(() =>
{
Console.WriteLine("task 运行开始");
Thread.Sleep(TimeSpan.FromSeconds(5));
Console.WriteLine("task 运行结束");
}, source.Token).ContinueWith(task => Console.WriteLine(task.Status));
source.Cancel();
Console.WriteLine("取消任务");
}
(…/media/1548577856869.png)]
Tasks are normally canceled
the reason
In fact, when Task.Run
the real task begins execution, calling CancellationSource.Cancel
the method does not cancel the task, or the end of the calling thread. Method Invocation still be carried out smoothly.
So with CancellationToken
method overloading what use is it?
1, as shown in the third example, the task before the start of operation, the call Cancel
can be directly cancel the task, avoid excessive consumption of a thread
2, when the corresponding token, in the execution thrown body OperationCanceledException
, (i.e. calls CancellationToken.ThrowIfCancellationRequested()
) which can be captured, and the task state is set toCanceled
public static async void Foo()
{
var source = new CancellationTokenSource();
Task.Run(() =>
{
Console.WriteLine("task 运行开始");
Thread.Sleep(TimeSpan.FromSeconds(5));
source.Token.ThrowIfCancellationRequested();
Console.WriteLine("task 运行结束");
},source.Token).ContinueWith(task => Console.WriteLine(task.Status));
await Task.Delay(TimeSpan.FromSeconds(3));
source.Cancel();
Console.WriteLine("取消任务");
}
And without the use of this overload, the task will be terminated due to an uncaught exception, not canceled
public static async void Foo()
{
var source = new CancellationTokenSource();
Task.Run(() =>
{
Console.WriteLine("task 运行开始");
Thread.Sleep(TimeSpan.FromSeconds(5));
source.Token.ThrowIfCancellationRequested();
Console.WriteLine("task 运行结束");
}).ContinueWith(task => Console.WriteLine(task.Status));
await Task.Delay(TimeSpan.FromSeconds(3));
source.Cancel();
Console.WriteLine("取消任务");
}
So we Task.Run
add CancellationToken
still need the manual to determine whether to cancel the token in the method of execution
Reference links:
- c# - How to cancel a running task? - Stack Overflow
- Task cancellation in C# and things you should know about it
- c# - Stop Task when task run - Stack Overflow
- Task.Run Method (System.Threading.Tasks) - Microsoft Docs
- Task Cancellation - Microsoft Docs
- How to: Cancel a Task and Its Children - Microsoft Docs
- How to: Use Parallel.Invoke to Execute Parallel Operations - Microsoft Docs
This article will be updated frequently, please read personal blog Original: https://xinyuehtx.github.io/ , in order to avoid misleading the old error of knowledge, and a better reading experience.
This work is Creative Commons Attribution - NonCommercial - ShareAlike 4.0 International License Agreement for licensing. Welcome to reprint, use, repost, but be sure to keep the article signed by Huang Tengxiao (containing links: https://xinyuehtx.github.io/ ), shall not be used for commercial purposes, be sure to publish the same work based on the paper license modification. If you have any questions, please contact me .