一、需求
假如调用一个异步方法后,一直不给返回值结果怎么办呢?这就涉及到怎么取消任务了。
二、Task取消任务
- static CancellationTokenSource source = new CancellationTokenSource();
- static void Main(string[] args)
- {
- Task.Run(() =>
- {
- for (int i = 0; i < 10; i++)
- {
- Thread.Sleep(500);
- Console.WriteLine("oh my god");
- source.Token.ThrowIfCancellationRequested();
- }
- }, source.Token);
- Thread.Sleep(2000);
- Console.WriteLine("取消任务");
- source.Cancel();
- Console.ReadKey();
- }
复制代码
换一个写法
- static void Main(string[] args)
- {
- bool isOut = false;
- var task1 = Task.Run(() =>
- {
- for (int i = 0; i < 100; i++)
- {
- if (isOut) return;
- Console.WriteLine("执行中" + i);
- Thread.Sleep(500);
- }
- });
- Thread.Sleep(2000);
- Console.WriteLine("取消任务");
- isOut = true;
- Console.ReadKey();
- }
复制代码 我在 for 循环中加入一个判断,假如等于 true,直接跳出循环,这不也可以中断任务
三、Task取消任务的回调
取消任务也是可以加入回调的,如下:
- static CancellationTokenSource source = new CancellationTokenSource();
- static void Main(string[] args)
- {
- var task1 = Task.Run(() =>
- {
- for (int i = 0; i < 100; i++)
- {
- source.Token.ThrowIfCancellationRequested();
- Console.WriteLine("执行中" + i);
- Thread.Sleep(500);
- }
- }, source.Token);
- //在指定的毫秒数后取消task执行
- source.CancelAfter(2 * 1000);
- //取消任务后的回调
- source.Token.Register(() =>
- {
- //不延迟会获取不到正确的状态
- Thread.Sleep(50);
- Console.WriteLine("task1状态:" + task1.Status);
- Console.WriteLine("IsFaulted状态:" + task1.IsFaulted);//由于未处理的异常,任务已完成。
- Console.WriteLine("IsCompleted状态:" + task1.IsCompleted);//获取一个值,该值指示任务是否已完成。
- });
- Console.ReadKey();
- }
复制代码
四、Task超时处置惩罚的实现
先来一个超时取消后续代码实验的方法
- private static CancellationTokenSource Cancellation = new CancellationTokenSource();
- static void Main(string[] args)
- {
- //设置超时的时间
- Cancellation.CancelAfter(TimeSpan.FromSeconds(1));
- Task.Run(() =>
- {
- try
- {
- Console.WriteLine("方法执行开始");
- //异步 Task.Delay 可以这么写,await Task.Delay(3000, Cancellation.Token)
- //效果同 Cancellation.Token.ThrowIfCancellationRequested()
- //await Task.Delay(3000, Cancellation.Token);
- Thread.Sleep(2000);
- Cancellation.Token.ThrowIfCancellationRequested();
- Console.WriteLine("方法执行结束");
- }
- catch (OperationCanceledException)
- {
- Console.WriteLine("取消操作");
- }
- });
- Console.ReadKey();
- }
复制代码
可以看到,方法实验结束这段代码并没有打印,这就是我们想要的结果了,在上面我们设置的超时时间是1秒,在后面的实验中,使用了线程睡眠时间是2秒,超时后,就主动取消操作了
把超时时间改为3秒,看看结果
- private static CancellationTokenSource Cancellation = new CancellationTokenSource();
- static void Main(string[] args)
- {
- //设置超时的时间
- Cancellation.CancelAfter(TimeSpan.FromSeconds(3));
- Task.Run(() =>
- {
- try
- {
- Console.WriteLine("方法执行开始");
- //异步 Task.Delay 可以这么写,await Task.Delay(3000, Cancellation.Token)
- //效果同 Cancellation.Token.ThrowIfCancellationRequested()
- //await Task.Delay(3000, Cancellation.Token);
- Thread.Sleep(2000);
- Cancellation.Token.ThrowIfCancellationRequested();
- Console.WriteLine("方法执行结束");
- }
- catch (OperationCanceledException)
- {
- Console.WriteLine("取消操作");
- }
- });
- Console.ReadKey();
- }
复制代码
这回就没有取消任务的实验了,那么超时取消代码实验的结果就实现了。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |