C#使用CancellationTokenSource 取消 Task的方法

 更新时间:2022年02月14日 10:55:10   作者:White_Hacker  
因为涉及到了日常经常会碰到的取消任务操作,本文主要介绍了C#使用CancellationTokenSource 取消 Task,文中通过代码介绍的非常详细,感兴趣的可以了解一下

本篇的内容也很重要,因为涉及到了日常经常会碰到的取消任务操作。

从我个人了解到的情况,基本上大家都采用CancellationTokenSource方法来取消任务,因此这里就举几个简单的例子。例子依然是来自于《C#多线程编程实战》。

private static int TaskMethod(string name, int seconds, CancellationToken token)
{
Console.WriteLine("Task {0} 运行在线程 {1} 上。是否是线程池线程: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
for (int i = 0; i < seconds; i ++)
{
Thread.Sleep(1000);
if (token.IsCancellationRequested) return -1;
}
return 42*seconds;
}

Task的取消采用一种形如令牌(Token)的方式。首先先构建一个CancellationTokenSource实例,而后在需要调用的操作(函数)参数中添加一个CancellationToken参数,也就是说, 取消是要求增加函数参数的。以上TaskMethod方法中可以看出,函数使用循环检查的方式来检测在seconds秒内,外部是否下达取消指令。当IsCancellationRequested时,那么将会返回-1.

接下来,先看一下如果Task没有被运行就直接取消,会发生什么。

var cts = new CancellationTokenSource();
var longTask = new Task<int>(() => TaskMethod("Task 1", 10, cts.Token), cts.Token);
Console.WriteLine("取消前,第一个任务的状态:{0}", longTask.Status);
cts.Cancel(); //取消任务!
Console.WriteLine("取消后,第一个任务的状态:{0}",longTask.Status);
Console.WriteLine("第一个任务在被执行前就已经取消了!");

接下来,我们来看看start()后再cancel()的情况。示例中每隔半秒打印一下longTask的状态:

var cts = new CancellationTokenSource();
var longTask = new Task<int>(() => TaskMethod("Task 2", 10, cts.Token), cts.Token);
longTask.Start(); //启动任务
for (int i = 0; i < 5; i++)
{
Thread.Sleep(TimeSpan.FromSeconds(0.5));
Console.WriteLine(longTask.Status);
}
cts.Cancel();
for (int i = 0; i < 5; i++)
{
Thread.Sleep(TimeSpan.FromSeconds(0.5));
Console.WriteLine(longTask.Status);
}
 
Console.WriteLine("A task has been completed with result {0}.", longTask.Result);

特别需要说明的是,在cancel了以后,任务状态显示为RanToCompletion,这是因为从TPL的视角看,这个任务虽然取消了,但是它正常完成了工作并且返回了-1.

到此这篇关于C#使用CancellationTokenSource 取消 Task的方法的文章就介绍到这了,更多相关C# 取消 Task内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#中委托用法

    C#中委托用法

    这篇文章主要介绍了C#中委托用法,实例分析了C#的定义与使用技巧,需要的朋友可以参考下
    2015-05-05
  • C#通过DataSet读写xml文件的方法

    C#通过DataSet读写xml文件的方法

    这篇文章主要介绍了C#通过DataSet读写xml文件的方法,涉及C#使用DataSet操作XML的相关技巧,方法简单实用,需要的朋友可以参考下
    2015-05-05
  • 不使用qvod播放器获取qvod播放路径的方法

    不使用qvod播放器获取qvod播放路径的方法

    这篇文章主要介绍了使用c#获取qvod播放路径的方法,大家参考使用吧
    2014-01-01
  • C#中处理JSON数据的方式示例详解

    C#中处理JSON数据的方式示例详解

    在C#中,可以使用System.Text.Json和Newtonsoft.Json这两个流行的库来将对象序列化为JSON字符串,本文给大家介绍C#中处理JSON数据的方式,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • 基于C#制作一个休息提醒闹钟的详细步骤

    基于C#制作一个休息提醒闹钟的详细步骤

    小闹钟大家都应该很熟悉,它包括时间、事件,当达到某某时间时,事件发生了,并且还有一个提示信息,下面这篇文章主要给大家介绍了关于如何基于C#制作一个休息提醒闹钟的详细步骤,需要的朋友可以参考下
    2023-02-02
  • C#实现简单的计算器小功能

    C#实现简单的计算器小功能

    这篇文章主要为大家详细介绍了C#实现简单的计算器小功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • C# 面向对象的基本原则

    C# 面向对象的基本原则

    什么是面向对象的基本原则?设计原则是基本的工具,应用这些规则可以使你的代码更加灵活、更容易维护,更容易扩展。
    2009-11-11
  • Unity实现透视滑动列表

    Unity实现透视滑动列表

    这篇文章主要为大家详细介绍了Unity实现透视滑动列表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • C#并行编程之数据并行Tasks.Parallel类

    C#并行编程之数据并行Tasks.Parallel类

    这篇文章介绍了C#并行编程之数据并行Tasks.Parallel类,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • C#中overrid和new修饰符有什么不同

    C#中overrid和new修饰符有什么不同

    在C#的继承中尝尝会用到相关的修饰词:override和new。这两个修饰符都可以在新的子类中,重写同名的父类方法。下面通过本文给大家介绍C#中overrid和new修饰符的区别,感兴趣的朋友一起看看吧
    2018-02-02

最新评论