接上文 多线程编程学习笔记——任务并行库(一)

接上文 多线程编程学习笔记——任务并行库(二)

接上文 多线程编程学习笔记——任务并行库(三)

接上文 多线程编程学习笔记——任务并行库(四)

通过前面的文章,已经学习了怎么使用线程,怎么使用线程同步,怎么使用线程池,怎么使用任务并行库。尽管通过上面的学习,对于线程的使用越来越简单。有没有更简单的方法呢。

C# 5.0之后,微软在c#语言中添加了两个关键字async与await,这是在TPL上面的更高一级的抽象,真正简化了异步编程的编程方式,从而有助于我们编写出真正健壮少bug的异步应用程序。下面我先来看一个最简单的示例。

async Task<string> AsyncHello()
{ await Task.Delay(TimeSpan.FromSeconds());
Return “ Hello world”;
}

使用async标记异步函数,建议返回async Task<T>。

Await只能使用在有async标志的方法内部。在async标记的方法内部最少要有一个await,当然,如果一个也没有,编译也不会报错,但是会有编译警告。如下图。

上面的代码在执行完await调用的代码之行后该方法会直接返回。如果同步执行,执行线程会阻塞2秒之后返回结果,本示例里在执行完await操作后,立即将工作线程放回线程池中,我们会异步等待。2秒后,我们会从线程池中取得工作线程并继续运行其中剩余的异步方法。这就允许我们在等待的2秒的时间里可以重用线程池中的线程,这对提高应用程序的可伸缩性非常重要。通过使用async与await我们拥有了线性的程序控制流程,但是执行过程却是异步的。

一、   使用await获取异步操作结果

本示例是学习await如何获取异步操作结果。同时会与TPL进行比较。

1.示例代码如下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading; namespace ThreadAsyncDemo
{ class Program
{
static void Main(string[] args)
{ Task t = AsyncWithTPL();
t.Wait();
t = AsyncWithAwait();
t.Wait();
Console.Read();
} static Task AsyncWithTPL()
{
Task<string> task1 = GetInfoAsync("Task 1"); Task task2 = task1.ContinueWith(task =>
Console.WriteLine(task1.Result), TaskContinuationOptions.NotOnFaulted);
Task task3 = task1.ContinueWith(task =>
Console.WriteLine(task1.Exception.InnerException), TaskContinuationOptions.OnlyOnFaulted);
return Task.WhenAny(task2, task1); } async static Task AsyncWithAwait()
{
try
{
string result = await GetInfoAsync("Task 4");
Console.WriteLine(result);
} catch (Exception ex)
{
Console.WriteLine(ex.Message); }
} async static Task<string> GetInfoAsync(string name)
{ await Task.Delay(TimeSpan.FromSeconds());
//throw new Exception("抛出异常信息!"); return string.Format(" Task {0} 正在运行在线程 ID={1}上。这个工作线程是否是线程池中的线程:{2}", name,
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); }
}
}

2.程序运行的结果如下图。

程序同时运行了两个异步操作。其中一个是标准的TPL代码,另一个使用了async与await两个关键字。AsyncWithTPL启动了一个任务,运行两秒之后返回关于工作线程信息的字符串。然后我们定义了一个后续操作,用于在异步操作完成后打印出操作结果,还有另一个后续操作,用于万一有错误时,打印出异常信息。最终返回了一个代表其中一个后续操作任务的任务,并等等其在主函数中完成。

在asyncWithAwait方法中,我们对任务使用await并得到了相同 的结果。这和编写普通的同步代码的风格一样,即我们获取了任务的结果,打印了出来,如果任务完成时带有错误则捕获异常。关键不同的是这实际上是一个异步操作。使用await后,c#立即创建了一个任务,其中一个有后续操作任务,包含了await操作符后面的所有剩余代码。这个新任务也处理了异常。然后这个任务返回 到主方法并等待共完成 。

因此可以看出程序中的两段代码在概念上是相同的,使用await由编译 器隐式地处理了异步代码。

3. 我们把上面注释的抛出异常的代码,取消注释,然后运行程序。得到如下图的结果。

注:在gui与asp.net之类的环境 中不推荐 使用task.wait和taskResult方法同,因为如果代码写的不好,很容易导致死锁。

二、   在Lambda表达式中使用await操作符

本示例学习如何在lambda表达式中使用await。将学习如何编写一个使用了await的匿名方法,并且获取异步执行该方法的结果。

1.示例代码如下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading; namespace ThreadAsyncDemo
{ class Program
{ static void Main(string[] args)
{ Task t = AsyncProcess();
t.Wait();
Console.Read();
} async static Task AsyncProcess()
{ Func<String, Task<string>> asyncLambda = async name =>
{ await Task.Delay(TimeSpan.FromSeconds());
return string.Format(" Task {0} 正在运行在线程 ID={1}上。这个工作线程是线程池的线程:{2}" ,name,
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
}; string result = await asyncLambda("async lambda");
Console.WriteLine(result); } } }

2.程序运行结果,如下图。

首先不能在main方法中使用async,我们将异步函数移到了asyncProcess中,然后使用async关键字声明了一个lambda表达式。由于 任何lambda表达式的类型都不能通过lambda自身来推断,所以不得不显示地指定类型为一字符串,并返回一个Task<string>对象 。

然后,我们定义 了lambda表达式体,这个方法虽然定义返回的是一个Task<string>对象 ,但实际上返回的是字符串,却没有编译错误。这是因为c#编译器自动 产生了一个任务并返回给我们。

最后一步就是打印出lambda 表达式执行后的结果。

多线程编程学习笔记——async和await(一)的更多相关文章

  1. 多线程编程学习笔记——async和await(二)

    接上文 多线程编程学习笔记——async和await(一) 三.   对连续的异步任务使用await操作符 本示例学习如何阅读有多个await方法方法时,程序的实际流程是怎么样的,理解await的异步 ...

  2. 多线程编程学习笔记——async和await(三)

    接上文 多线程编程学习笔记——async和await(一) 接上文 多线程编程学习笔记——async和await(二) 五.   处理异步操作中的异常 本示例学习如何在异步函数中处理异常,学习如何对多 ...

  3. 多线程编程学习笔记——使用异步IO(一)

    接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...

  4. 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端

    接上文 多线程编程学习笔记——使用异步IO 二.   编写一个异步的HTTP服务器和客户端 本节展示了如何编写一个简单的异步HTTP服务器. 1.程序代码如下. using System; using ...

  5. 多线程编程学习笔记——异步调用WCF服务

    接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 接上文 多线程编程学习笔记——异步操作数据库 本示例描述了如何创建一个WCF服务,并宿主 ...

  6. 多线程编程学习笔记——使用异步IO

    接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...

  7. [Java123] JDBC and Multi-Threading 多线程编程学习笔记

    项目实际需求:DB交互使用多线程实现 多线程编程基础:1.5  :( (假设总分10) 计划一个半月从头学习梳理Java多线程编程基础以及Oracle数据库交互相关的多线程实现 学习如何通过代码去验证 ...

  8. Java多线程编程(学习笔记)

    一.说明 周末抽空重新学习了下多线程,为了方便以后查阅,写下学习笔记. 有效利用多线程的关键是理解程序是并发执行而不是串行执行的.例如:程序中有两个子系统需要并发执行,这时候需要利用多线程编程. 通过 ...

  9. python学习笔记 async and await

    用asyncio提供的@asyncio.coroutine可以把一个generator标记为coroutine类型,然后在coroutine内部用yield from调用另一个coroutine实现异 ...

随机推荐

  1. Strange fuction

    Strange fuction Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...

  2. BootStrap Table使用小结

    1.在当前表格的最后新增数据 $("#data_module_table").bootstrapTable('append', data.data);//data.data---- ...

  3. css中单位 px、em 的区别【转载】

    原文:http://www.admin10000.com/document/6267.html     在国内网站中,包括三大门户,以及“引领”中国网站设计潮流的蓝色理想,ChinaUI等都是使用了p ...

  4. 百度Echarts导入

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  5. 深入分析Android动画(一)

    动画的分类: ①View动画 View动画顾名思义其作用对象为View,包含平移.缩放.旋转.透明,这四类变化分别对应着Animation的子类TranlateAnimation.ScaleAnima ...

  6. ueditor插入百度音乐无法播放-403 问题

    简单记录一下,其实403是因为百度音乐设置了禁止外部连接引用,因此 几乎所有的百度音乐播放都会提示403. 注意:预览页面(dialog/music/music.html)和实际插入页面(uedito ...

  7. Linux系列教程(十六)——Linux权限管理之ACL权限

    通过前面的两篇博客我们介绍了Linux系统的用户管理,Linux用户和用户组管理之相关配置文件 讲解了用户管理的相关配置文件,包括用户信息文件/etc/passwd,用户密码文件/etc/shadow ...

  8. ML技术 - 特征选择

    1. 决策树中的特征选择 分类决策树是一种描述对实例进行分类的树型结构,决策树学习本质上就是从训练数据集中归纳出一组分类规则,而二叉决策树类似于if-else规则.决策树的构建也是非常的简单,首先依据 ...

  9. C#实现阿拉伯数字(小写金额)到大写中文(大写金额)的转换

    /// <summary>    /// 本类实现阿拉伯数字到大写中文的转换    /// 该类没有对非法数字进行判别,请事先自己判断数字是否合法    /// </summary& ...

  10. 基于 Aspose.Cells与XML导入excel 数据----操作类封装

    前言 导入excel数据, 在每个项目中基本上都会遇到,第三方插件或者基于微软office,用的最多的就是npoi,aspose.cells和c#基于office这三种方式,其中各有各的优缺点,在这也 ...