Task CancellationTokenSource和Task.WhenAll的应用
Task是.net4.0推出的异步编程类,与ThreadPool.QueneUserWorkItem方法类似的是,Task也是使用线程池来工作的.但Task比起这个QueneUserWorkItem的优势是它的可控制性,能够通过CancellationTokenSource控制Task运行任务的取消,还能够知道Task运行任务是何时完成的.Task对线程的阻塞控制有静态方法WaitAll(params Task[] tasks)我的理解是,当所有的tasks都完成得时候线程就不会阻塞,WaitAny(params Task[] tasks))表示只要tasks中其中任意一个任务完成,线程就不会再是阻塞状态.,成员方法Wait方法有四个重载,它们分别是:
- public void Wait()
- public bool Wait(TimeSpan timeout)
- public void Wait(CancellationToken cancellationToken)
- public bool Wait(int millisecondsTimeout)
- public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
对于Task的介绍就到这里,下面来看看它的一个例子,这个例子,我要做的就是:当点击按钮时,用两个任务t2,t3来sleep5秒钟,同时用任务t1在uI界面死循环的更新listbox读秒时间,当t2,t3任务结束了,在利用Task.WenAll和CancellationTokenSource break掉t1的死循环。效果如图所示:

代码如下:
CancellationTokenSource cts = new CancellationTokenSource();
        private void button1_Click(object sender, EventArgs e)
        {
            Task t2 = new Task(() =>
            {
                Thread.Sleep();
            });
            //為了说明Task的异步,t2 和 t3都sleep5秒,但程序只数了5秒就结束了,这间接说明t2和t3是异步的
            Task t3 = new Task(() =>
            {
                Thread.Sleep();
            });
            //死循环读秒
            Task t1 = new Task((obj) =>
            {
                object[] objs = obj as object[];
                CancellationTokenSource cancellationToken = objs[] as CancellationTokenSource;//这个控制任务取消的
                string strParam = objs[].ToString();
                int i = ;
                while (true)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }
                    if (listBox1.InvokeRequired)
                    {
                        listBox1.Invoke(new Action(() =>
                        {
                            listBox1.Items.Add(strParam + ":" + i++);
                        }));
                    }
                    else
                    {
                        listBox1.Items.Add(strParam + ":" + i++);
                    }
                    Delay();
                }
            }, new object[] { cts, "params" }, cts.Token);//这里随便写了一个参数,当任务需要参数的时候就“{ cts, "params" }“这样传,并且把控制任务取消的令牌cts.Token传进去
if (button1.Text == "start")
{ button1.Text = "sleep...";
t1.Start(); t2.Start();
t3.Start();
Task task = Task.WhenAll(t2, t3);//这个WhenAll不会像WaitAll那样阻塞线程,所以会在t2和t3都sleep的情况下执行t1那个死循环线程
//这里在建一个死循环任务去判断task是否完成
Task.Run(() =>
{
while (true)
{
if (task.IsCompleted)//当t2和t3都完成得时候,这里就为true
{
cts.Cancel();//这里是对Task的取消操作,当执行了这句话时,这里cancellationToken.IsCancellationRequested就变成true
MessageBox.Show("結束!"); break; } } }); } }
大概就是这样,Task.WenAll是异步的是不会阻塞线程的。
Task CancellationTokenSource和Task.WhenAll的应用的更多相关文章
- task CancellationTokenSource
		使用CancellationTokenSource对象需要与Task对象进行配合使用,Task会对当前运行的状态进行控制(这个不用我们关心是如何控制的).而CancellationTokenSourc ... 
- 第八节:Task的各类Task<TResult>返回值以及通用线程的异常处理方案。
		一. Task的各种返回值-Task<TResult> PS: 在前面章节,我们介绍了Task类开启线程.线程等待.线程延续的方式,但我们并没有关注这些方式的返回值,其实他们都是有返回值的 ... 
- 【C# Task】 ValueTask/Task<TResult>
		概要 1.如果异步方法的使用者使用 Task.WhenAll 或 Task.WhenAny,则在异步方法中使用 ValueTask<T> 作为返回类型可能会产生高昂的成本.这是因为您需要使 ... 
- Task.Run Vs Task.Factory.StartNew
		在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至 ... 
- Task.Run Vs Task.Factory.StartNew z
		在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至 ... 
- MapReduce作业的map task和reduce task调度参数
		MapReduce作业可以细分为map task和reduce task,而MRAppMaster又将map task和reduce task分为四种状态: 1.pending:刚启动但尚未向reso ... 
- C# Task的使用---Task的启动
		.NET 4.0包含的新名称空间System.Threading.Tasks,它包含的类抽象出了线程功能.任务表示应完成的某个单元的工作.这个单元的工作可以在单独的线程中运行,也可以以同步的方式启动一 ... 
- .Net4.0如何实现.NET4.5中的Task.Run及Task.Delay方法
		前言 .NET4.0下是没有Task.Run及Task.Delay方法的,而.NET4.5已经实现,对于还在使用.NET4.0的同学来说,如何在.NET4.0下实现这两个方法呢? 在.NET4.0下, ... 
- Task.Run与Task.Factory.StartNew的区别
		Task是可能有延迟的工作单元,目的是生成一个结果值,或产生想要的效果.任务和线程的区别是:任务代表需要执行的作业,而线程代表做这个作业的工作者. 在.Net 4中,Task.Factory.Star ... 
随机推荐
- [乐意黎原创]Centos 7里apache(httpd)自启动
			最近,Aerchi在折腾 ECS服务器 (Centos 7),每次重启后都要手动开启apache服务,好繁琐. 仔细研究了下:Apache 的服务第一.启动.终止.重启systemctl start ... 
- C# Redis分布式锁(基于ServiceStack.Redis)
			相关的文章其实不少,我也从中受益不少,但是还是想自己梳理一下,毕竟自己写的更走心! 首先给出一个拓展类,通过拓展方法实现加锁和解锁. 注:之所以增加拓展方法,是因为合理使用拓展类(方法),可以让程序更 ... 
- Linux搭建基于BIND的DNS服务器
			Linux搭建基于BIND的DNS服务器 实验目标: 通过本实验掌握基于Linux的DNS服务器搭建. 实验步骤: 1.安装BIND 2.防火墙放通DNS服务 3.编辑BIND的主配置文件 4.编 ... 
- Spring 入门程序
			1.0 导包的时候要注意: 以上的第一个是.class文件 以上的第二个是文件的解释性页面. 以上的第三个是.java文件 2.0 配置文件需要导入依赖(有dtd 依赖,也有xsd依赖) ² 从be ... 
- 开源SQL审核平台——Archery 安装、部署心得
			目录 0.软件版本及项目地址 1.安装python venv环境 1.1.安装 python36 1.2.创建 Python venv 环境(Python>=3.6.5,建议使用虚拟环境 ) 1 ... 
- WebLogic 任意文件上传远程代码执行_CVE-2018-2894漏洞复现
			WebLogic 任意文件上传远程代码执行_CVE-2018-2894漏洞复现 一.漏洞描述 Weblogic管理端未授权的两个页面存在任意上传getshell漏洞,可直接获取权限.Oracle 7月 ... 
- React躬行记(7)——表单
			表单元素是一类拥有内部状态的元素,这些状态由其自身维护,通过这类元素可让用户与Web应用进行交互.HTML中的表单元素(例如<input>.<select>和<radio ... 
- Python 定义自己的常量类
			在实际的程序开发中,我们通常会将一个不可变的变量声明为一个常量.在很多高级语言中都会提供常量的关键字来定义常量,如 C++ 中的 const , Java 中的 final 等,但是 Python 语 ... 
- C# 与 JS 之间传值在 cshtml页面中
			@{ string It = "sss"; ; } @functions{ string Mod = "ajssaioi"; public string Itm ... 
- 网页缓存相关的HTTP头部信息详解
			前言 之前看完了李智慧老师著的<大型网站技术架构-核心原理与案例分析>这本书,书中多次提起浏览器缓存的话题,恰是这几天生产又遇到了一个与缓存的问题,发现自己书是没少看,正经走心的内容却不多 ... 
