C# Task任务详解及其使用方式
https://blog.csdn.net/younghaiqing/article/details/81455410
C#多线程编程笔记(4.3)-Task任务中实现取消选项
https://blog.csdn.net/qq_35445058/article/details/80829339
1.Task类介绍:
Task 类的表示单个操作不返回一个值,通常以异步方式执行。 Task 对象是一个的中心思想 基于任务的异步模式 首次引入.NET Framework 4 中。 因为由执行工作 Task 对象通常以异步方式执行在线程池线程上而不是以同步方式在主应用程序线程,您可以使用 Status 属性,以及 IsCanceled, ,IsCompleted, ,和 IsFaulted 属性,以确定任务的状态。 大多数情况下,lambda 表达式用于指定的任务是执行的工作。
对于返回值的操作,您使用 Task 类。
任务Task和线程Thread的区别:
1、任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执行。
2、任务跟线程不是一对一的关系,比如开10个任务并不是说会开10个线程,这一点任务有点类似线程池,但是任务相比线程池有很小的开销和精确的控制。
Task和Thread一样,位于System.Threading命名空间下!
一、创建Task
Task 类还提供了构造函数对任务进行初始化,但的未计划的执行。 出于性能原因, Task.Run 或 TaskFactory.StartNew(工厂创建) 方法是用于创建和计划计算的任务的首选的机制,但对于创建和计划必须分开的方案,您可以使用的构造函数(new一个出来),然后调用 Task.Start 方法来计划任务,以在稍后某个时间执行。
//第一种创建方式,直接实例化:必须手动去Start
var task1 = new Task(() =>
{
//TODO you code
});
task1.Start();
//第二种创建方式,工厂创建,直接执行
var task2 = Task.Factory.StartNew(() =>
{
//TODO you code
});
二、Task的简略生命周期:
| 方法名 | 说明 |
|---|---|
| Created | 表示默认初始化任务,但是“工厂创建的”实例直接跳过。 |
| WaitingToRun | 这种状态表示等待任务调度器分配线程给任务执行。 |
| RanToCompletion | 任务执行完毕。 |
//查看Task中的状态
var task1 = new Task(() =>
{
Console.WriteLine("Begin");
System.Threading.Thread.Sleep(2000);
Console.WriteLine("Finish");
});
Console.WriteLine("Before start:" + task1.Status);
task1.Start();
Console.WriteLine("After start:" + task1.Status);
task1.Wait();
Console.WriteLine("After Finish:" + task1.Status);
Console.Read();
三、Task的任务控制:Task最吸引人的地方就是他的任务控制了,你可以很好的控制task的执行顺序,让多个task有序的工作
| 方法名 | 说明 |
|---|---|
| Task.Wait | task1.Wait();就是等待任务执行(task1)完成,task1的状态变为Completed。 |
| Task.WaitAll | 待所有的任务都执行完成: |
| Task.WaitAny | 发同Task.WaitAll,就是等待任何一个任务完成就继续向下执行 |
| Task.ContinueWith | 第一个Task完成后自动启动下一个Task,实现Task的延续 |
| CancellationTokenSource | 通过cancellation的tokens来取消一个Task。 |
下面详细介绍一下上面的几个方法:
1、Task.Wait
task1.Wait();就是等待任务执行(task1)完成,task1的状态变为Completed。
2、Task.WaitAll
看字面意思就知道,就是等待所有的任务都执行完成:
{
Task.WaitAll(task,task2,task3...N)
Console.WriteLine("All task finished!");
}
即当task,task2,task3…N全部任务都执行完成之后才会往下执行代码(打印出:“All task finished!”)
3、Task.WaitAny
这个用发同Task.WaitAll,就是等待任何一个任务完成就继续向下执行,将上面的代码WaitAll替换为WaitAny
{
Task.WaitAny(task,task2,task3...N)
Console.WriteLine("Any task finished!");
}
即当task,task2,task3…N任意一个任务都执行完成之后就会往下执行代码(打印出:” Any task finished!”)
4、Task.ContinueWith
就是在第一个Task完成后自动启动下一个Task,实现Task的延续,下面我们来看下他的用法,编写如下代码:
static void Main(string[] args)
{
var task1 = new Task(() =>
{
Console.WriteLine("Task 1 Begin");
System.Threading.Thread.Sleep(2000);
Console.WriteLine("Task 1 Finish");
});
var task2 = new Task(() =>
{
Console.WriteLine("Task 2 Begin");
System.Threading.Thread.Sleep(3000);
Console.WriteLine("Task 2 Finish");
});
task1.Start();
task2.Start();
var result = task1.ContinueWith<string>(task =>
{
Console.WriteLine("task1 finished!");
return "This is task result!";
});
Console.WriteLine(result.Result.ToString());
Console.Read();
}
可以看到,task1完成之后,开始执行后面的内容,并且这里我们取得task的返回值。
5、Task的取消
前面说了那么多Task的用法,下面来说下Task的取消,比如我们启动了一个task,出现异常或者用户点击取消等等,我们可以取消这个任务。如何取消一个Task呢,我们通过cancellation的tokens来取消一个Task。在很多Task的Body里面包含循环,我们可以在轮询的时候判断IsCancellationRequested属性是否为True,如果是True的话就return或者抛出异常,抛出异常后面再说,因为还没有说异常处理的东西。
下面在代码中看下如何实现任务的取消,代码如下:
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var task = Task.Factory.StartNew(() =>
{
for (var i = 0; i < 1000; i++)
{
System.Threading.Thread.Sleep(1000);
if (token.IsCancellationRequested)
{
Console.WriteLine("Abort mission success!");
return;
}
}
}, token);
token.Register(() =>
{
Console.WriteLine("Canceled");
});
Console.WriteLine("Press enter to cancel task...");
Console.ReadKey();
tokenSource.Cancel();
这里开启了一个Task,并给token注册了一个方法,输出一条信息,然后执行ReadKey开始等待用户输入,用户点击回车后,执行tokenSource.Cancel方法,取消任务。
注:
- 因为任务通常运行以异步方式在线程池线程上,创建并启动任务的线程将继续执行,一旦该任务已实例化。 在某些情况下,当调用线程的主应用程序线程,该应用程序可能会终止之前任何任务实际开始执行。 其他情况下,应用程序的逻辑可能需要调用线程继续执行,仅当一个或多个任务执行完毕。 您可以同步调用线程的执行,以及异步任务它启动通过调用 Wait 方法来等待要完成的一个或多个任务。 若要等待完成一项任务,可以调用其 Task.Wait 方法。 调用 Wait 方法将一直阻塞调用线程直到单一类实例都已完成执行。
参考文献:
1.https://www.cnblogs.com/yunfeifei/p/4106318.html
2.https://msdn.microsoft.com/zh-cn/library/system.threading.tasks.task.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
using System;
using System.Threading.Tasks;
using System.Threading; namespace 实现取消选项
{
class Program
{
static void Main(string[] args)
{
var cts = new CancellationTokenSource();
var longTask = new Task<int>(() => TaskMethod("Task 1", 10, cts.Token), cts.Token);
Console.WriteLine(longTask.Status);
cts.Cancel();
Console.WriteLine(longTask.Status);
Console.WriteLine("First task has been cancelled before execution"); cts = new CancellationTokenSource();
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);
Console.ReadKey();
}
private static int TaskMethod(string name,int seconds,CancellationToken token)
{
Console.WriteLine("Task {0} is running on a thread id {1},Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread);
for (int i = 0; i < seconds; i++)
{
Thread.Sleep(TimeSpan.FromSeconds(1));
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancel Task {0} is running on a thread id {1},Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread);
return -1;
}
}
return 42 * seconds;
}
}
}
C# Task任务详解及其使用方式的更多相关文章
- JavaScript---Dom树详解,节点查找方式(直接(id,class,tag),间接(父子,兄弟)),节点操作(增删改查,赋值节点,替换节点,),节点属性操作(增删改查),节点文本的操作(增删改查),事件
JavaScript---Dom树详解,节点查找方式(直接(id,class,tag),间接(父子,兄弟)),节点操作(增删改查,赋值节点,替换节点,),节点属性操作(增删改查),节点文本的操作(增删 ...
- Spring task任务调度详解
spring内部有一个task是Spring自带的一个设定时间自动任务调度 task使用的时候很方便,但是他能做的东西不如quartz那么的多! 可以使用注解和配置两种方式,配置的方式如下 引入Spr ...
- Spring之AOP原理、代码、使用详解(XML配置方式)
Spring 的两大核心,一是IOC,另一个是AOP,本博客从原理.AOP代码以及AOP使用三个方向来讲AOP.先给出一张AOP相关的结构图,可以放大查看. 一.Spring AOP 接口设计 1.P ...
- Activity的task相关 详解
task是一个具有栈结构的容器,可以放置多个Activity实例.启动一个应用,系统就会为之创建一个task,来放置根Activity:默认情况下,一个Activity启动另一个Activity时,两 ...
- js if for 详解 获取元素方式 及一些js 基础知识
##获取元素的新方法## --document.querySelector('Css Selector{css选择器}') 接收一个css选择器(通配,群组,类,包含,id....等) 若这个选择器对 ...
- Spring AOP详解和实现方式
一.什么是AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善. ...
- Spring系列(四):Spring AOP详解和实现方式(xml配置和注解配置)
参考文章:http://www.cnblogs.com/hongwz/p/5764917.html 一.什么是AOP AOP(Aspect Oriented Programming),即面向切面编程, ...
- 利用EPX Studio将C/S程序转成B/S的方法详解(在线模块方式)
采用 EPX 的在线模块,是最简单的方法,包括实现简单,客户端不需任何设置,客户使用就简单. 1. 设置服务器端参数(EPServer) 1.1 在服务配置工具选项卡中,设置服务项中的名称,路径,激活 ...
- Kubernetes ConfigMap详解,多种方式创建、多种方式使用
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 配置是程序绕不开的话题,在Kubernetes中使用ConfigMap来配置,它本质其实就是键值对.本文讲解如何 ...
随机推荐
- pytorch--cpu与gpu load时相互转化
pytorch------cpu与gpu load时相互转化 torch.load(map_location=)学习 将gpu改为cpu时,遇到一个报错:RuntimeError: Attemptin ...
- openfire服务器开发环境搭建
2017-07-26 更新:直接获取最新版源码,就不会报错了,而且可支持的插件多,老版本的openfire几乎没有可用的官方插件. 系统及软件环境: MAC OSX EI Capitan 10.11. ...
- mesos的zookeeper变更
采用rpm方式安装你了mesos,碰到zookeeper(采用了cloudera的zookeeper)的IP地址变化了,肿么办? 在master机器中: /etc/mesos/zk进行编辑修改zk路径 ...
- BZOJ4010:[HNOI2015]菜肴制作
我对贪心的理解:https://www.cnblogs.com/AKMer/p/9776293.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem ...
- form+iframe实现ajax文件上传
在做文件上传时除了传入文件外,还有附件参数,并且要求不刷新页面,之前是表单提交的方式,现在修改成ajax上传的方式,由于没有选择用插件,所以用form+iframe的方式,并且这种方式对IE8以上及主 ...
- HDU1114(完全背包装满问题)
Piggy-Bank Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- app专项测试(稳定性测试、安全性测试)
https://blog.csdn.net/xiaomaoxiao336368/article/details/84887948
- Makefile经典教程
转自:http://blog.csdn.net/ruglcc/article/details/7814546/ makefile很重要 什么是makefile?或许很多Winodws的程序 ...
- delphi 线程教学第三节:设计一个有生命力的工作线程
第三节:设计一个有生命力的工作线程 创建一个线程,用完即扔.相信很多初学者都曾这样使用过. 频繁创建释放线程,会浪费大量资源的,不科学. 1.如何让多线程能多次被复用? 关键是不让代码退出 ...
- 基于STM32的三轴数字罗盘HMC5883L模块的测试
最近买了个数字罗盘模块,调通后发现很不错,非常灵敏,测试的时候精度在1°以内.连续测量模式下,最快测量.输出速率可达75hz,模块每次测量完毕并将数据更新至寄存器后,其DRDY引脚便产生一个低电平脉冲 ...