Framework4.5语法糖 异步Task
2016-05-06 11:20
381 查看
1、线程安全
在使用TaskRun的时候需要注意线程安全的问题。
线程安全通常是由全局变量及静态变量引起的,如果是值类型就不存在这样的隐患,如果是引用类型用不好就会导致线程不安全!
2、Task、Task<T>存在的意义
这问题困扰了我很久,包括到现在还是有问题没想明白。
Task可以等同于void的线程,那么Task能节约时间是能理解的。
Task<T>能省时间吗?答案是能,Debug的时候我曾陷入一个误区,误认为Task<T>的方法是串行的,其实是并行的,比如有3个异步方法,方法1耗时3秒,方法2耗时6秒,方法3耗时4秒,串行肯定是13秒,但在Task<T>下3个方法是并行的,总耗时约等于最长耗时的方法2也就是6秒。脑部一下3个方法在同时执行,方法1先结束并返回值、方法3接着结束并返回值,方法2最后结束并返回返回值。如果在总方法里面还有一个var m=a+b+c,则m可理解为3个方法都结束后再来调用。
OK,上面举得例子是3个无关的方法,加入方法2的参数是方法1的返回值,又是什么情况呢?实践证明,framework已经把它处理成了方法2必须等待方法1全部执行完才执行,也就是总耗时为3+6=9秒,方法三的时间在并行时自动节约掉了!!
View Code
我的疑问:下面异步的写法有没有意义??
2、注意事项
2.1、僵尸式蔓延,从底层异步,需要衍生到顶部,不要中间层又改成同步,会出现死锁现象
2.2、多用await,少用.wait()
在使用TaskRun的时候需要注意线程安全的问题。
线程安全通常是由全局变量及静态变量引起的,如果是值类型就不存在这样的隐患,如果是引用类型用不好就会导致线程不安全!
2、Task、Task<T>存在的意义
这问题困扰了我很久,包括到现在还是有问题没想明白。
Task可以等同于void的线程,那么Task能节约时间是能理解的。
Task<T>能省时间吗?答案是能,Debug的时候我曾陷入一个误区,误认为Task<T>的方法是串行的,其实是并行的,比如有3个异步方法,方法1耗时3秒,方法2耗时6秒,方法3耗时4秒,串行肯定是13秒,但在Task<T>下3个方法是并行的,总耗时约等于最长耗时的方法2也就是6秒。脑部一下3个方法在同时执行,方法1先结束并返回值、方法3接着结束并返回值,方法2最后结束并返回返回值。如果在总方法里面还有一个var m=a+b+c,则m可理解为3个方法都结束后再来调用。
OK,上面举得例子是3个无关的方法,加入方法2的参数是方法1的返回值,又是什么情况呢?实践证明,framework已经把它处理成了方法2必须等待方法1全部执行完才执行,也就是总耗时为3+6=9秒,方法三的时间在并行时自动节约掉了!!
using System; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { DateTime dtBegin = DateTime.Now; var delayTask = DisplayValue(); DisplayValue3(); int x = delayTask.Result; var delayTask2 = DisplayValue2(x); int y = delayTask2.Result; DateTime dtEnd = DateTime.Now; Console.Write(x + "|" + y + "|" + (dtEnd - dtBegin).TotalSeconds); Console.Read(); } #region 方法一 public static async Task<int> DisplayValue() //public static int DisplayValue() { int i = 1; int result = await Task.Run(() => { for (; i < 10; i++) { Thread.Sleep(300); SqlHelper.ExecuteNonQuery("insert into TestTable select '" + i + "'"); } return i; }); return result; } #endregion #region 方法二 public static async Task<int> DisplayValue2(int x) //public static int DisplayValue2() { int i = 1; var m = await Task.Run(() => { for (; i < 10; i++) { Thread.Sleep(x); SqlHelper.ExecuteNonQuery("insert into TestTable select '" + i * 100 + "'"); } return i; }); return m; } #endregion #region 方法三 //public static async Task DisplayValue3() public static void DisplayValue3() { //await Task.Run(() => //{ for (int i = 1; i < 10; i++) { Thread.Sleep(500); SqlHelper.ExecuteNonQuery("insert into TestTable select '" + i * 1000 + "'"); } //}); } #endregion } }
View Code
我的疑问:下面异步的写法有没有意义??
public ActionResult TopMenu(string CurrentAppId) { //DisplayValue(CurrentAppId); return View(); } public async Task<ActionResult> TopMenu(string CurrentAppId) { return View(); }
2、注意事项
2.1、僵尸式蔓延,从底层异步,需要衍生到顶部,不要中间层又改成同步,会出现死锁现象
2.2、多用await,少用.wait()
相关文章推荐
- centos7 pxe minimal install
- dijkstra算法
- Sublime 导出带有颜色的代码
- java 实现WebService 以及不同的调用方式
- 【C语言】逆序输出字符串
- lua深度克隆的实现(lua基本数据类型传的是值,表类型传的是引用)
- C++第五次上机实验—教师干部类
- 手机最顶端的状态栏
- 第十周-阅读程序
- 代理模式(二)
- java集合03--ArrayList源码分析
- VC 6.0快捷键大全
- vim配置颜色方案
- 设计模式之模板方法模式
- 高德地图使用心得,百度地图使用心得
- 【深入理解JVM】:Java类继承关系中的初始化顺序
- WebApi集成Swagger
- "https://open.gl/"教程之Transforms源码(freeglut版)
- 【iCore3 双核心板_FPGA】实验十五:基于USART的ARM与FPGA通信实验
- sql 优化