C#的async和await
C# 5.0中引入了async 和 await。这两个关键字可以让你更方便的写出异步代码。
看个例子:
- public class MyClass
- {
- public MyClass()
- {
- DisplayValue(); //这里不会阻塞
- System.Diagnostics.Debug.WriteLine("MyClass() End.");
- }
- public Task<double> GetValueAsync(double num1, double num2)
- {
- return Task.Run(() =>
- {
- for (int i = 0; i < 1000000; i++)
- {
- num1 = num1 / num2;
- }
- return num1;
- });
- }
- public async void DisplayValue()
- {
- double result = await GetValueAsync(1234.5, 1.01);//此处会开新线程处理GetValueAsync任务,然后方法马上返回
- //这之后的所有代码都会被封装成委托,在GetValueAsync任务完成时调用
- System.Diagnostics.Debug.WriteLine("Value is : " + result);
- }
- }
上面在MyClass的构造函数里调用了async关键字标记的异步方法DisplayValue(),DisplayValue()方法里执行了一个await关键字标记的异步任务GetValueAsync(),这个异步任务必须是以Task或者Task<TResult>作为返回值的,而我们也看到,异步任务执行完成时实际返回的类型是void或者TResult,DisplayValue()方法里await GetValueAsync()之后的所有代码都会在异步任务完成时才会执行。
DisplayValue()方法实际执行的代码如下:
- public void DisplayValue()
- {
- System.Runtime.CompilerServices.TaskAwaiter<double> awaiter = GetValueAsync(1234.5, 1.01).GetAwaiter();
- awaiter.OnCompleted(() =>
- {
- double result = awaiter.GetResult();
- System.Diagnostics.Debug.WriteLine("Value is : " + result);
- });
- }
可以看到,async和await关键字只是把上面的代码变得更简单易懂而已。
程序的输出如下:
MyClass() End.
Value is : 2.47032822920623E-322
以下是我写的一个静态类,可以方便将一个普通Function执行异步调用:
- public static class TaskAsyncHelper
- {
- /// <summary>
- /// 将一个方法function异步运行,在执行完毕时执行回调callback
- /// </summary>
- /// <param name="function">异步方法,该方法没有参数,返回类型必须是void</param>
- /// <param name="callback">异步方法执行完毕时执行的回调方法,该方法没有参数,返回类型必须是void</param>
- public static async void RunAsync(Action function, Action callback)
- {
- Func<System.Threading.Tasks.Task> taskFunc = () =>
- {
- return System.Threading.Tasks.Task.Run(() =>
- {
- function();
- });
- };
- await taskFunc();
- if (callback != null)
- callback();
- }
- /// <summary>
- /// 将一个方法function异步运行,在执行完毕时执行回调callback
- /// </summary>
- /// <typeparam name="TResult">异步方法的返回类型</typeparam>
- /// <param name="function">异步方法,该方法没有参数,返回类型必须是TResult</param>
- /// <param name="callback">异步方法执行完毕时执行的回调方法,该方法参数为TResult,返回类型必须是void</param>
- public static async void RunAsync<TResult>(Func<TResult> function, Action<TResult> callback)
- {
- Func<System.Threading.Tasks.Task<TResult>> taskFunc = ()=>
- {
- return System.Threading.Tasks.Task.Run(()=>
- {
- return function();
- });
- };
- TResult rlt = await taskFunc();
- if(callback != null)
- callback(rlt);
- }
- }
使用很简单,将方法名作为参数传进去就行了,最常用的是把很耗时的序列化函数传进去,以免阻塞UI进程,造成卡顿现象,影响用户体验。
C#的async和await的更多相关文章
- [译] C# 5.0 中的 Async 和 Await (整理中...)
C# 5.0 中的 Async 和 Await [博主]反骨仔 [本文]http://www.cnblogs.com/liqingwen/p/6069062.html 伴随着 .NET 4.5 和 V ...
- 探索c#之Async、Await剖析
阅读目录: 基本介绍 基本原理剖析 内部实现剖析 重点注意的地方 总结 基本介绍 Async.Await是net4.x新增的异步编程方式,其目的是为了简化异步程序编写,和之前APM方式简单对比如下. ...
- Async和Await异步编程的原理
1. 简介 从4.0版本开始.NET引入并行编程库,用户能够通过这个库快捷的开发并行计算和并行任务处理的程序.在4.5版本中.NET又引入了Async和Await两个新的关键字,在语言层面对并行编程给 ...
- 异步方法的意义何在,Async和await以及Task的爱恨情仇,还有多线程那一家子。
前两天刚感受了下泛型接口的in和out,昨天就开始感受神奇的异步方法Async/await,当然顺路也看了眼多线程那几个.其实多线程异步相关的类单个用法和理解都不算困难,但是异步方法Async/awa ...
- 多线程之异步编程: 经典和最新的异步编程模型,async与await
经典的异步编程模型(IAsyncResult) 最新的异步编程模型(async 和 await) 将 IAsyncInfo 转换成 Task 将 Task 转换成 IAsyncInfo 示例1.使用经 ...
- 浅谈async、await关键字 => 深谈async、await关键字
前言 之前写过有关异步的文章,对这方面一直比较弱,感觉还是不太理解,于是会花点时间去好好学习这一块,我们由浅入深,文中若有叙述不稳妥之处,还请批评指正. 话题 (1)是不是将方法用async关键字标识 ...
- 使用 Async 和 Await 的异步编程(C# 和 Visual Basic)[msdn.microsoft.com]
看到Microsoft官方一篇关于异步编程的文章,感觉挺好,不敢独享,分享给大家. 原文地址:https://msdn.microsoft.com/zh-cn/library/hh191443.asp ...
- 【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单
一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两 ...
- C#基础系列——异步编程初探:async和await
前言:前面有篇从应用层面上面介绍了下多线程的几种用法,有博友就说到了async, await等新语法.确实,没有异步的多线程是单调的.乏味的,async和await是出现在C#5.0之后,它的出现给了 ...
- C# Async与Await的使用
这个是.NET 4.5的特性,所以要求最低.NET版本为4.5. 看很多朋友还是使用的Thread来使用异步多线程操作,基本上看不见有使用Async.Await进行异步编程的.各有所爱吧,其实都可以. ...
随机推荐
- 【OpenStack】OpenStack系列3之Swift详解
Swift安装部署(与keystone依赖包有冲突,需要安装不同版本eventlet) 参考:http://www.server110.com/openstack/201402/6662.html h ...
- 《转》.NET开源核心运行时,且行且珍惜
转载自infoQ 背景 InfoQ中文站此前报道过,2014年11月12日,ASP.NET之父.微软云计算与企业级产品工程部执行副总裁Scott Guthrie,在Connect全球开发者在线会议上宣 ...
- Balanced Binary Tree
Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary ...
- div隐藏
<div style="display:none"> <textarea id="BodyBox2" runa ...
- Eclipse 一直提示 loading descriptor for 的解决方法(转)
启动eclipse之后,进行相关操作时,弹出界面,提示:loading descriptor for xxx 解决方法: 在Eclipse左侧的Project Explorer 最右上角有一个小钮,鼠 ...
- iOS的 context 和Android 中的 canvas
ios 想要绘图,要用到CGContextRef类.最基本的用法是在- (void)drawRect:(CGRect)rect 函数中绘制. Android 中要用到Canvas类.最基本的用法是在 ...
- docke跨主机通信之gre隧道
GRE简介 GRE可以对网络层的任何协议来进行封装,类似LVS的IPIP协议,在原有的数据报上增加GRE协议数据报.然后在网络上传输,到达对端后,解开GRE数据报头,得到真实的数据报.其中的mac地址 ...
- C++基础(1)
1.关于继承及访问. C++中 public,protected, private 访问标号小结,即访问标号使用限制. 第一:private, public, protected 访问标号的访问范围. ...
- linux常见问题集锦-2
http://zhangge.net/1986.html 在此感谢作者分享 1.linux如何挂在windows下的共享目录 Shell 1 mount.cifs //192.168.1.3/serv ...
- 烟大 Contest1024 - 《挑战编程》第一章:入门 Problem B: Minesweeper(模拟扫雷)
Problem B: Minesweeper Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 29 Solved: 7[Submit][Status][W ...