1.Task.Delay实质是创建一个任务,再任务中开启一个定时间,然后延时指定的时间
2.Task.Delay不和await一起使用情况,当代码遇到Task.Delay一句时,创建了了一个新的任务去执行延时去了,当前代码继续往下执行
3.Task.Delay和await一起使用,当代码遇到await Task.Delay时候,当前线程要等该行代码执行完成后,再继续执行后面的代码
namespace Cancel
{
internal class Program
{
static void Main(string[] args)
{
CancellationTokenSource source = new CancellationTokenSource();
var t = Task.Run( async delegate//匿名方法配合委托使用
{
await Task.Delay(5000, source.Token);//只有await会报错,有了await必须有async,
//反过来,只有async不报错,但执行到 Task.Delay()就不会停止,直接执行下面代码
return 42;
});
source.Cancel();//Task.Delay()相对于Thread.Sleep()的好处,可以自己控制取消
try
{
//此时引发TaskCanceledException异常
t.Wait();
}
catch (AggregateException ae)//source.Cancel()实际上是抛出一个请求,引发一个异常
{
foreach (var e in ae.InnerExceptions)
Console.WriteLine("{0}: {1}", e.GetType().Name, e.Message);
}
//WaitingForActivation状态就是在await另外一个线程
Console.Write("Task t Status: {0}", t.Status);
if (t.Status == TaskStatus.RanToCompletion)
Console.Write(", Result: {0}", t.Result);
source.Dispose();
//这是换一种方法呈现
//try
//{
// CancellationTokenSource cts = new CancellationTokenSource();
// Task task= Execute(cts.Token);
// Console.WriteLine($"[AsyncMethodDemo] AsyncMethod()返回值为 {task}");
// // 手动取消任务
// cts.Cancel();
// task.Wait();//注释掉这一行不会捕捉到异常
//}
//catch (AggregateException ae)
//{
// foreach (var e in ae.InnerExceptions)
// Console.WriteLine("{0}: {1}", e.GetType().Name, e.Message);
//}
Console.ReadKey();
}
static async Task Execute(CancellationToken token)
{
await Task.Delay(5000, token);//新开一个线程,持续时间是3s
Console.WriteLine("Executed");
}
}
}
里面涵盖了一些多线程的相关知识,可以改写调试一下。
罒ω罒 把Token丢进线程就像放了一个军用机器人,遥控器在自己手上,需要停止(取消线程) 时按下按钮(Cancel)即可。
声明:借鉴1.C# 在时间延迟后完成的可取消任务 Task.Delay(int millisecondsDelay, CancellationToken cancellationToken)-CSDN博客