Task.WaitAll代替WaitHandle.WaitAll
Task.Waitall阻塞了当前线程直到全完。whenall开启个新监控线程去判读括号里的所有线程执行情况并立即返回,等都完成了就退出监控线程并返回监控数据。
task.Result会等待异步方法返回,当然阻塞住了。别和await 同时用。
Task和ThreadPool的功能类似,可以用来创建一些轻量级的并行任务。对于将一个任务放进线程池
ThreadPool.QueueUserWorkItem(A);
这段代码用Task来实现的话,方式如下:
Task.Factory.StartNew(A);
这两端代码的使用和实现的功能都十分相似。但和TheadPool相比,Task有着更多的功能,更加方便我们使用。
假如我们要创建三个任务,并等待它们完成。这个功能用TheadPool实现如下:
using (ManualResetEvent mre1 = new ManualResetEvent(false))
using (ManualResetEvent mre2 = new ManualResetEvent(false))
using (ManualResetEvent mre3 = new ManualResetEvent(false))
{
ThreadPool.QueueUserWorkItem(delegate
{
A();
mre1.Set();
});
ThreadPool.QueueUserWorkItem(delegate
{
B();
mre2.Set();
});
ThreadPool.QueueUserWorkItem(delegate
{
C();
mre3.Set();
});
WaitHandle.WaitAll(new WaitHandle[] { mre1, mre2, mre3 });
}
用Task类实现起来就相对简单多了:
Task t1 = Task.Factory.StartNew(delegate { A(); });
Task t2 = Task.Factory.StartNew(delegate { B(); });
Task t3 = Task.Factory.StartNew(delegate { C(); });
t1.Wait();
t2.Wait();
t3.Wait();
或者我们还可以这么写:
Task t1 = Task.Factory.StartNew(delegate { A(); });
Task t2 = Task.Factory.StartNew(delegate { B(); });
Task t3 = Task.Factory.StartNew(delegate { C(); });
Task.WaitAll(t1, t2, t3);
下面我们来简单的介绍一下Task的基本用法:
创建Task
创建Task有两种方式
- 通过构造函数创建
Task t1 = new Task(A); - 通过TaskFactory创建
Task t1 = Task.Factory.StartNew(A);
这两种方式其实是一样的,第一种方式里面也传入了默认的TaskFactory——Task.Factory。TaskFactory起着对Task进行创建和调度管理的作用,类似于以前CTP版中的TaskManager,关于这个对象,后续会单独写一篇文章介绍。
开始运行Task
在上述两种创建Task方式中,方式1创建的Task并没有立即执行,需要手动调用t1.Start()来执行(类似于线程,需要手动执行)。而方式2创建的Task是立即执行的(类似于线程池,是自动执行的),从这两种方式的函数名称也可以看出这一点。
等待Task完成
等待Task完成的也有两种:
- 调用Task的成员函数t.Wait()。
- 调用Task的静态函数Task.WaitAll()或Task.WaitAny()。
这两种方式和.net中常用的WaitHandle差不多,这里就不多介绍了。
取消Task
取消Task的方式较CTP的时候复杂和强大了不少,后续加一个单独的篇章单独介绍。
异常处理
当Task在执行过程中发生异常时,该异常会在Wait或WaitAll等函数中重新throw。可以通过Task的Exception属性来获取发生的异常。
var t1 = Task.Factory.StartNew(() => { throw new Exception("t1 error occor"); });
var t2 = Task.Factory.StartNew(() => { throw new Exception("t2 error occor"); });
try
{
Task.WaitAll(t1, t2);
}
catch (Exception)
{
Console.WriteLine(t1.Exception.InnerException.Message);
Console.WriteLine(t2.Exception.InnerException.Message);
}
获取Task的返回值
在CTP版本中,是通过Fucture<>类来获取带返回值的Task的,现在已经将类改名为Task<>了,从而实现命名方式的统一。使用方式几乎一致,就是多了一个Result属性,可以在Task执行完成后获取返回值。示例如下:
var t1 = Task.Factory.StartNew(() => 3);
t1.Wait();
Console.WriteLine(t1.Result);
Task.WaitAll代替WaitHandle.WaitAll的更多相关文章
- WaitHandle.WaitAll 方法在WPF工程中的应用
因为WaiAll需要多线程支持, 而WPF是STA模式, 可以通过以下方式实现WaitAll ManualResetEvent[] events: foreach (ManualResetEvent ...
- WaitAny, WaitAll 和 SignalAndWait
除了Set 和 WaitOne方法外,在类WaitHandle中还有一些用来创建复杂的同步过程的静态方法. WaitAny, WaitAll 和 SignalAndWait使跨多个可能为不同类型的等待 ...
- C# Task 用法
C# Task 的用法 其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观.代码更简洁了,使用Task来进行操作.可以跟线程一样可以轻松的对执行的方法进行控制. 顺便提一下, ...
- 线程 线程池 Task
首先声明 这是读了 愉悦的绅士 文章 <菜鸟之旅——学习线程(线程和线程池)> <Task与线程> 的一些个人总结,还是那句话,如有不对,欢迎指正 文章以代码加注释的方法展示. ...
- .Net4.0并行库介绍——Task
Task和ThreadPool的功能类似,可以用来创建一些轻量级的并行任务.对于将一个任务放进线程池 ThreadPool.QueueUserWorkItem(A); 这段代码用Task来实现 ...
- (译).NET4.X并行任务Task需要释放吗?
摘要:本博文解释在.NET 4.X中的Task使用完后为什么不应该调用Dispose().并且说明.NET4.5对.NET4.0的Task对象进行的部分改进:减轻Task对WaitHandle对象的依 ...
- C# Task的用法
C# Task 的用法 其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观.代码更简洁了,使用Task来进行操作.可以跟线程一样可以轻松的对执行的方法进行控制. 顺便提一下, ...
- 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq
常量,字段,构造方法 常量 1.什么是常量 常量是值从不变化的符号,在编译之前值就必须确定.编译后,常量值会保存到程序集元数据中.所以,常量必须是编译器识别的基元类型的常量,如:Boolean ...
- C#的WaitHandle : 管理多线程状态
有时候,我们创建了多线程,需要知道是否都完成了各自的工作.比如说,开启了多线程的下载,如何终止所有的线程并且在确保所有线程都终止之后才继续执行程序的退出呢? public partial class ...
随机推荐
- 遍历DOM树,each()遍历
在<jQuery教程/理解选取更新范围>一节中,我们知道:当选择器返回了多个元素时,可以使用一个方法来更新所有的元素,不再需要使用循环. 然后有的时候需要遍历元素,怎么办? 使用each( ...
- android手机 解锁bootloader 刷recovery 线刷rom 卡刷rom
1 解锁bootloader 为手机安装官方驱动 按相应的组合键使手机进入fastboot模式 执行命令fastboot oem unlock 123456 (123456为厂家提供的解锁码) 手机重 ...
- Javascript中call、apply之我见
一.call和apply定义. 1.Call 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 参数 thisObj 可选项.将被用作当前对象的对象. arg ...
- 解决C3P0在Linux下Failed to get local InetAddress for VMID问题
解决C3P0在Linux下Failed to get local InetAddress for VMID问题 FailedtogetlocalInetAddressforVMID.Thisisunl ...
- js正则表达式子校验
//正则表达式校验new RegExp(/^[1-9]\d{4,8}$/,"g").test(1234);//执行一个字符串所表达的方法 eval(this['字符串']) 正则表 ...
- xshell连接不上linux情况一
设置网络的地址使用桥接方式
- zookeeper 常用cLi命令
官网:https://zookeeper.apache.org/doc/r3.4.8/zookeeperAdmin.html#sc_zkCommands stat path [watch] set p ...
- 04_web基础(七)之jsp
39.jsp与el表达式引入 JSP:Java Server Pages:Java的服务网页(Java动态网页):=========================================== ...
- Transparency Sort Mode
[Transparency Sort Mode] Transparency Sort Mode, which allows you to control how Sprites are sorted ...
- C# delegate (001)
背景:一直不是很理解C#中的委托,也不是很清楚委托应用的业务场景,有可能和自己一直做B/S有关 业务描述:C/S,父窗口打开子窗口,子窗口把自己文本框里的值传个父窗口的文本框. 子窗体代码: //定义 ...