这是两个关键字,用于异步编程。我们传统的异步编程方式一般是Thread、ThreadPool、BeginXXX、EndXXX等等。把调用、回调分开来,代码的逻辑是有跳跃的,于是会导致思路不是很清晰的问题,在.NET 4.5中,新推出的async、await关键字,可以帮助我们像写同步方法一样去写异步方法(保证代码的整齐清晰)。

  先来看个传统同步方法例子:

 1         static void Main(string[] args)
2 {
3 // 同步方式
4 Console.WriteLine("同步方式测试开始!");
5 SyncMethod(0);
6 Console.WriteLine("同步方式结束!");
7 Console.ReadKey();
8 }
9
10 // 同步操作
11 private static void SyncMethod(int input)
12 {
13 Console.WriteLine("进入同步操作!");
14 var result = SyancWork(input);
15 Console.WriteLine("最终结果{0}", result);
16 Console.WriteLine("退出同步操作!");
17 }
18
19 // 模拟耗时操作(同步方法)
20         private static int SyancWork(int val)
21 {
22 for (int i = 0; i < 5; ++i)
23 {
24 Console.WriteLine("耗时操作{0}", i);
25 Thread.Sleep(100);
26 val++;
27 }
28 return val;
29 }

  可以从右图中看到执行结果,是非常典型的同步执行方法。

  async关键字能用在方法、lambda表达式的声明部分,用来标示此方法可能包含await关键字,只有拥有async才能在其内部使用await关键字。异步方法可以具有Task、Task<>或void的返回类型;await关键字则是用于返回值是“可等待”类型(awaitable)的方法或lambda表达式内,“awaitable”可以是任何类型(常见的有Task、Task<>),它必须公开一个GetAwaiter() 方法并且返回有效的”awaiter”。更详细的信息可以参考“关于Async与Await的FAQ”,里面介绍了这些概念与注意事项。

  当一个async方法,且内部包含await关键字,它就会在编译的时候成为一个异步方法,如果没有await关键字,则它将只会被当成一个同步方法来执行。如果对其内部实现感兴趣可以参考“异步性能:了解 Async 和 Await 的成本”一文,相信对深入了解这种机制还是有所帮助的。

  现在我们尝试使用新出的异步关键字async、await来改造成异步调用:

        {
// 异步方式
Console.WriteLine("\n异步方式测试开始!");
AsyncMethod(0);
Console.WriteLine("异步方式结束!");
Console.ReadKey();
} // 异步操作
private static async void AsyncMethod(int input)
{
Console.WriteLine("进入异步操作!");
var result = await AsyncWork(input);
Console.WriteLine("最终结果{0}", result);
Console.WriteLine("退出异步操作!");
} // 模拟耗时操作(异步方法)
        private static async Task<int> AsyncWork(int val)
{
for (int i = 0; i < 5; ++i)
{
Console.WriteLine("耗时操作{0}", i);
await Task.Delay(100);
val++;
}
return val;
}

  先来看结果吧,我们发现耗时操作已经是异步进行了。整体流程大概是先由Main函数异步调用AsyncMethod,并不等待AsyncMethod完成,继续往下执行。而AsyncMethod方式在被调用后,在分配到时间片时开始启动,执行函数体内容,并由于await AsyncWork语句而继续异步调用AsyncWork,但由于await关键字,将在此等待AsyncWork完成后,再继续往下执行。那么,AyncWork也一样的,被调用后,在分配到时间片时开始启动,执行耗时操作。

  可以看到,使用了新的关键字后,同步与异步编程的语法差别进一步减少。随着.NET 4.5的推出,许多新类库和既有类库都支持这种新型的异步语法(比如HttpClient、HttpServer、MemoryStream...),它们以类似ReadAsync、WriteAsync、SendAsync等分开方法来提供具有async声明,且返回类型为Task、Task<>的异步工作方式。

  补充:

  刚才有朋友提到await Task.Delay(100)这条语句,这是为了让AsyncWork成为异步方法才加的,如果你要进行的操作不支持await修饰怎么办,其实很简单,使用Task.Factory.StartNew()就行了,举例:

 1         // 异步操作
2 private static async void AsyncMethod(int input)
3 {
4 Console.WriteLine("进入异步操作!");
5 var result = await Task.Factory.StartNew((Func<object, int>)SyncWork2, input);
6 Console.WriteLine("最终结果{0}", result);
7 Console.WriteLine("退出异步操作!");
8 }
9
10 // 模拟耗时操作(同步方法)
11 private static int SyncWork2(object input)
12 {
13 int val = (int)input;
14 for (int i = 0; i < 5; ++i)
15 {
16 Console.WriteLine("耗时操作{0}", i);
17 Thread.Sleep(100);
18 val++;
19 }
20 return val;
21 }

  这样,我们的SyncWork2实际上却是异步执行的,所得结果与前面的异步方法一致,只是这样一来输入参数只能是object类型,需要进行类型转化。另外,除了StartNew,我们还可以新建一个Task,然后调用Run,以完成同样效果。

.NET异步编程初识async与await的更多相关文章

  1. 异步编程(Async和Await)的使用

    .net4.5新特性之异步编程(Async和Await)的使用 一.简介 首先来看看.net的发展中的各个阶段的特性:NET 与C# 的每个版本发布都是有一个“主题”.即:C#1.0托管代码→C#2. ...

  2. .Net 4.5 异步编程初试(async和await)

    .Net 4.5 异步编程初试(async和await) 前言 最近自己在研究Asp.Net Web API.在看到通过客户端来调用Web API的时候,看到了其中的异步编程,由于自己之前没有接触过, ...

  3. C# 异步编程,async与await的简单学习

    前提声明:C# 5.0 .NET Framework 4.5 2012-08-15 异步和等待(async和await).调用方信息(Caller Information)  (C#版本与.NET版本 ...

  4. .NET4.5新特性之异步编程(Async和Await)的使用

    一.简介 首先来看看.net的发展中的各个阶段的特性:NET 与C# 的每个版本发布都是有一个"主题".即:C#1.0托管代码→C#2.0泛型→C#3.0LINQ→C#4.0动态语 ...

  5. 多线程之异步编程: 经典和最新的异步编程模型,async与await

    经典的异步编程模型(IAsyncResult) 最新的异步编程模型(async 和 await) 将 IAsyncInfo 转换成 Task 将 Task 转换成 IAsyncInfo 示例1.使用经 ...

  6. 《C#并发编程经典实例》学习笔记—异步编程关键字 Async和Await

    C# 5.0 推出async和await,最早是.NET Framework 4.5引入,可以在Visual Studio 2012使用.在此之前的异步编程实现难度较高,async使异步编程的实现变得 ...

  7. C# 异步编程4 async与await 异步程序开发

    随着C#异步程序开发系列的深入,你会发现编写异步程序越发简单.事物的发展就是这样的规律,从简单到复杂再到简单. 在C# 5.0中我们可以通过async与await关键字实现快捷的异步程序开发,如下: ...

  8. C# 异步编程(async&await)

    同步:同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去 异步:异步是指进程不需要一直等下去,而是继续执行下面的操作 ...

  9. ES7中前端异步特性:async、await。

    在最新的ES7(ES2017)中提出的前端异步特性:async.await. 什么是async.await? async顾名思义是"异步"的意思,async用于声明一个函数是异步的 ...

随机推荐

  1. c# 文件简繁体转换

    C#   文件简繁体转换 简繁体转换: 方案一: 准确性高,耗性能 方案二: 准确性低,效率高 1 using Microsoft.International.Converters.Tradition ...

  2. Mysql数据库连接、查询、记录集操作代码

    Mysql数据库链接代码 function dbConnect($hostname,$username,$pass,$db_name,$pconnect =0) { $func=empty($pcon ...

  3. LA 4255 Guess

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  4. 《Linux内核设计与实现》读书笔记(十)- 内核同步方法【转】

    转自:http://www.cnblogs.com/wang_yb/archive/2013/05/01/3052865.html 内核中提供了多种方法来防止竞争条件,理解了这些方法的使用场景有助于我 ...

  5. YTU 2618: B 求类中数据成员的最大值-类模板

    2618: B 求类中数据成员的最大值-类模板 时间限制: 1 Sec  内存限制: 128 MB 提交: 430  解决: 300 题目描述 声明一个类模板,类模板中有三个相同类型的数据成员,有一函 ...

  6. Python代码编辑器

    PyCharm Community 说到PyCharm Community,我们就会想到它是一款免费的开源Python代码编辑器,不过这也是事实啦.PyCharm Community为我们提供了轻量级 ...

  7. Mac 切换Windows 使用虚拟机, 不推荐双系统

     为什么使用虚拟机而不是双系统? 1.虚拟机可以随时在两个系统之间进行切换,便于在工作时使用而不影响效率.如果是双系统,在切换到另一个系统时需要关机重启,太过麻烦. 2.虚拟机除了运行Windows之 ...

  8. MTK6577 Android源代码目录

    MTK6577 Android源代码目录 1.     MTKAndroid4.0 源代码目录 (1)  makeMtk 整个工程编译或是构建(make/build)的入口. (2)  abi 应用程 ...

  9. 《OD大数据实战》HBase整合MapReduce和Hive

    一.HBase整合MapReduce环境搭建 1. 搭建步骤1)在etc/hadoop目录中创建hbase-site.xml的软连接.在真正的集群环境中的时候,hadoop运行mapreduce会通过 ...

  10. cocos2d-x 获取图片的某像素点的RGBA颜色 -转

    cocos2d-x 获取图片的某像素点的RGBA颜色  原文:http://www.cnblogs.com/jaoye/archive/2013/02/19/2916501.html 没做过 太多的图 ...