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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C#利用Task实现任务超时多任务一起执行的方法

    前言 其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观.代码更简洁了,使用Task来进行操作.可以跟线程一样可以轻松的对执行的方法进行控制. 创建Task有两种方式,一种是使用构造函数创建,另一种是使用 Task.Factory.StartNew 进行创建. 如下代码所示 1.使用构造函数创建Task Task t1 = new Task(MyMethod); 2.使用Task.Factory.StartNew 进行创建Task Task t1 = Task.Fact

  • C#多线程学习之Thread、ThreadPool、Task、Parallel四者区别

    目录 Thread ThreadPool Task Parallel Task专讲 线程(英语:thread)是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务.进程是资源分配的基本单位.所有与该进程有关的资源,都被记录在进程控制块PCB中.以表示该进程拥有这些资源或正在使用它们.本文以一些简单的小例子,简述多线程的发展历程[Thread,ThreadPool,Task

  • 详解C#中 Thread,Task,Async/Await,IAsyncResult的那些事儿

    说起异步,Thread,Task,async/await,IAsyncResult 这些东西肯定是绕不开的,今天就来依次聊聊他们 1.线程(Thread) 多线程的意义在于一个应用程序中,有多个执行部分可以同时执行:对于比较耗时的操作(例如io,数据库操作),或者等待响应(如WCF通信)的操作,可以单独开启后台线程来执行,这样主线程就不会阻塞,可以继续往下执行:等到后台线程执行完毕,再通知主线程,然后做出对应操作! 在C#中开启新线程比较简单 static void Main(string[]

  • c#异步task示例分享(异步操作)

    c# Task异步操作 复制代码 代码如下: using System;using System.Threading;using System.Threading.Tasks; namespace ConsoleApplication18{    class Program    {        static void Main(string[] args)        {            Func<string, string> _processTimeFunc = new Fun

  • 深入分析C# Task

    ​Task的MSDN的描述如下: [Task类的表示单个操作不会返回一个值,通常以异步方式执行. Task对象是一种的中心思想基于任务的异步模式首次引入.NETFramework 4 中. 因为由执行工作Task对象通常以异步方式执行线程池线程上而不是以同步方式在主应用程序线程中,可以使用Status属性,并将IsCanceled, IsCompleted,和IsFaulted属性,以确定任务的状态. 大多数情况下,lambda 表达式用于指定该任务所执行的工作量. 对于返回值的操作,您使用Ta

  • C# 并行和多线程编程——Task进阶知识

    一.Task的嵌套 Task中还可以再嵌套Task,Thread中能不能这样做,我只能说我是没这样写过.Task中的嵌套,我感觉其实也可以分开来写,不过嵌套起来会方便管理一点.Task中的嵌套分为两种,关联嵌套和非关联嵌套,就是说内层的Task和外层的Task是否有联系,下面我们编写代码先来看一下非关联嵌套,及内层Task和外层Task没有任何关系,还是在控制台程序下面,代码如下: static void Main(string[] args) { var pTask = Task.Factor

  • C#使用CancellationTokenSource 取消 Task的方法

    本篇的内容也很重要,因为涉及到了日常经常会碰到的取消任务操作. 从我个人了解到的情况,基本上大家都采用CancellationTokenSource方法来取消任务,因此这里就举几个简单的例子.例子依然是来自于<C#多线程编程实战>. private static int TaskMethod(string name, int seconds, CancellationToken token) { Console.WriteLine("Task {0} 运行在线程 {1} 上.是否是线

  • C# 使用CancellationTokenSource取消多线程

    目录 几点关键问题解释: 同时取消多个线程: 有时间我们在使用多线程的时候,需要取消线程的执行,可以使用CancellationTokenSource来取消对Task开辟多线程的取消 如下:我们点击一个按钮开启线程,然后点击取消按钮取消该线程的执行 CancellationTokenSource cts ; /// <summary> /// 开启线程 /// </summary> private void button1_Click(object sender, EventArg

  • 利用原生js和jQuery实现单选框的勾选和取消操作的方法

    根据以下的Demo,大概就可以看的明白 Demo: <html> <head> <script src='jquery-1.9.1.min.js'></script> <script> window.onload = function(){ var dom_a = document.getElementById('a1'); var dom_b = document.getElementById("b1"); //alert(

  • jQuery实现点击行选中或取消CheckBox的方法

    本文实例讲述了jQuery实现点击行选中或取消CheckBox的方法.分享给大家供大家参考,具体如下: /// <summary> /// 点击行选中或者取消CheckBox /// </summary> /// <param name="TableID">表ID</param> function SetCheckBox_Check(TableID) { var $TableID = TableID == "" ? &

  • layer关闭当前窗口页面以及确认取消按钮的方法

    如下所示: function demo() { layer.confirm('您是如何看待前端开发?', { btn: ['重要','奇葩'] //按钮 }, function(){ var index = parent.layer.getFrameIndex(window.name); parent.layer.close(index);//关闭当前页 layer.msg('的确很重要', {icon: 1}); }, function(){ layer.msg('也可以这样', { time

  • layer弹出层取消遮罩的方法

    layer 只是作为 layui 的一个弹层模块 layer弹出层取消遮罩 笔者认为 跟 layer弹出层非模态对话框类似 layer.open({ title: '在线调试', content: '可以填写任意的layer代码', shade:0 }); shade - 遮罩 类型:String/Array/Boolean,默认:0.3 即弹层外区域.默认是0.3透明度的黑色背景('#000').如果你想定义别的颜色,可以shade: [0.8, '#393D49']:如果你不想显示遮罩,可以

  • 微信小程序实现动态设置placeholder提示文字及按钮选中/取消状态的方法

    本文实例讲述了微信小程序实现动态设置placeholder提示文字及按钮选中取消状态的方法.分享给大家供大家参考,具体如下: 效果图展示    通过绑定点击事件placeholder方法,获取data-num的值,通过js判断num等于几,然后通过class="{{num==X?'active':''}}"表达式判断哪个标签处于选中状态(即蓝底白字): js通过获取data-key,设置input输入框中placeholder的动态值 wxml里的内容: <view class=

  • C#中的Task.WhenAll和Task.WhenAny方法介绍

    一.简介 Task.WhenAll().Task.WhenAny()这两个与Task.WaitALL().Task.WaitAny()是有区别的,When是异步的,Wait是同步的.Task.WhenAll():所有提供的任务已完成时,创建将完成的任务.Task.WhenAny():任何提供的任务已完成时,创建将完成的任务. 二.代码案例 Task.WhenAll 代码: class Program { public class DownLoadTest { Stopwatch watch =

  • C#连续任务Task.ContinueWith方法

    一.简介 通过任务,可以指定在任务完成之后,应开始运行之后另一个特定任务.ContinueWith是Task根据其自身状况,决定后续应该作何操作.也就是说,在运行完task后,会执行task.continuewith(XX)中的XX语句,但是是否执行.如何执行等需要看task的运行情况.例如:一个使用前一个任务的结果的新任务,如果前一个任务失败了,这个任务就应执行一些清理工作.任务处理程序都不带参数或者带一个对象参数,而任务的连续处理方法都有一个Task类型的参数. 二.案例 案例一: 代码:

  • C#中的Task.WaitAll和Task.WaitAny方法介绍

    一.简介 Task.WaitAll:等待所有提供的 Task 对象完成执行过程. Task.WaitAny:等待提供的任一 Task 对象完成执行过程. 二.代码案例 Task.WaitAll 代码: class Program { public class DownLoadTest { Stopwatch watch = new Stopwatch(); public DownLoadTest() { watch.Start(); } public async Task DoRunTaskAs

随机推荐