第十节:利用async和await简化异步编程模式的几种写法
2018-01-14 18:51
621 查看
一. async和await简介
PS:简介
1. async和await这两个关键字是为了简化异步编程模型而诞生的,使的异步编程跟简洁,它本身并不创建新线程,但在该方法内部开启多线程,则另算。
2. 这两个关键字适用于处理一些文件IO操作。
3. 好处:代码简介,把异步的代码写成了同步的形式,提高了开发效率。
坏处:如果使用同步思维去理解,容易出问题,返回值对不上。
二. 几种用法
情况1:当只有async,没有await时,方法会有个警告,和普通的多线程方法没有什么区别,不存在线程等待的问题。
代码实践:
代码结果:
情况2:不推荐void返回值,使用Task来代替Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行。
代码实践:
代码结果:
情况3:async Task == async void。 区别:Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行。
代码实践:
代码结果:
情况4和情况5:说明要使用子线程中的变量,一定要等子线程执行结束后再使用。
代码实践:
代码结果:
以上两种情况,第一种情况含有线程等待的结果为4950,第二个情况么有线程等待,结果不准确(即共享变量竞用问题)。
PS:简介
1. async和await这两个关键字是为了简化异步编程模型而诞生的,使的异步编程跟简洁,它本身并不创建新线程,但在该方法内部开启多线程,则另算。
2. 这两个关键字适用于处理一些文件IO操作。
3. 好处:代码简介,把异步的代码写成了同步的形式,提高了开发效率。
坏处:如果使用同步思维去理解,容易出问题,返回值对不上。
二. 几种用法
情况1:当只有async,没有await时,方法会有个警告,和普通的多线程方法没有什么区别,不存在线程等待的问题。
代码实践:
private static async void Test1() { //主线程执行 Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId); //启动新线程完成任务 Task task = Task.Run(() => { Console.WriteLine("子线程{0}开始:", Thread.CurrentThread.ManagedThreadId); Thread.Sleep(3000); Console.WriteLine("子线程{0}结束:", Thread.CurrentThread.ManagedThreadId); }); //主线程执行 Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId); }
代码结果:
情况2:不推荐void返回值,使用Task来代替Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行。
代码实践:
/// <summary> /// 不推荐void返回值,使用Task来代替 /// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用。async Void 不行 /// </summary> private static async void Test2() { //主线程执行 Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId); //启动新线程完成任务 Task task = Task.Run(() => { Console.WriteLine("子线程{0}开始:", Thread.CurrentThread.ManagedThreadId); Thread.Sleep(3000); Console.WriteLine("子线程{0}结束:", Thread.CurrentThread.ManagedThreadId); }); await task; //等待子线程执行完毕,方可执行后面的语句 Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId); }
代码结果:
情况3:async Task == async void。 区别:Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行。
代码实践:
/// <summary> /// 无返回值 async Task == async void /// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行 /// </summary> private static async Task Test3() { //主线程执行 Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId); //启动新线程完成任务 Task task = Task.Run(() => { Console.WriteLine("子线程{0}开始:", Thread.CurrentThread.ManagedThreadId); Thread.Sleep(3000); Console.WriteLine("子线程{0}结束:", Thread.CurrentThread.ManagedThreadId); }); await task; //等待子线程执行完毕,方可执行后面的语句 Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId); }
代码结果:
情况4和情况5:说明要使用子线程中的变量,一定要等子线程执行结束后再使用。
代码实践:
/// <summary> /// 带返回值的Task,要使用返回值,一定要等子线程计算完毕才行 /// </summary> /// <returns></returns> private static async Task<long> Test4() { //主线程执行 Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId); long result = 0; //启动新线程完成任务 Task task = Task.Run(() => { for (long i = 0; i < 100; i++) { result += i; } }); await task; //等待子线程执行完毕,方可执行后面的语句 Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId); Console.WriteLine("result:{0}", result); return result; }
/// <summary> /// 带返回值的Task,要使用返回值,一定要等子线程计算完毕才行 /// 与情况四形成对比,没有等待,最终结果不准确 /// </summary> /// <returns></returns> private static Task<long> Test5() { //主线程执行 Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId); long result = 0; //启动新线程完成任务 TaskFactory taskFactory = new TaskFactory(); Task<long> task = taskFactory.StartNew<long>(() => { for (long i = 0; i < 100; i++) { result += i; } return 1; }); Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId); Console.WriteLine("result:{0}", result); return task; }
代码结果:
以上两种情况,第一种情况含有线程等待的结果为4950,第二个情况么有线程等待,结果不准确(即共享变量竞用问题)。
相关文章推荐
- Async和Await如何简化异步编程,几个实例让你彻底明白!
- silverlight学习之路(2)异步编程趋于同步 利用async和await调用wcf服务
- Async和Await如何简化异步编程,几个实例让你彻底明白!
- [.NET] 利用 async & await 的异步编程
- 在WCF中使用async/await 关键字的简化的异步编程模型(译)
- 单例模式的几种写法(包含双检锁写法)
- .NET4.5新特性之异步编程(Async和Await)的使用
- 单例模式java中的几种写法和确保多线程下安全
- 单例模式学习及几种不同写法
- 单列设计模式几种写法的比较
- 单例模式的几种写法
- android 几种单例模式的写法
- 不使用回调函数的ajax请求实现(async和await简化回调函数嵌套)
- C#~异步编程再续~await与async引起的w3wp.exe崩溃
- 利用Lambda表达式简化命令者模式
- C++中几种常见的单例模式写法。
- .Net异步编程之Async与Await的使用
- java的单例模式几种写法
- java中单例模式的几种写法
- Java多线程编程-单例模式几种写法的错与对