多线程编程学习笔记——async和await(一)

时间:2022-11-12 17:45:22

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

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

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

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

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

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,当然,如果一个也没有,编译也不会报错,但是会有编译警告。如下图。

多线程编程学习笔记——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.程序运行的结果如下图。

多线程编程学习笔记——async和await(一)

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

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

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

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

多线程编程学习笔记——async和await(一)

注:在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.程序运行结果,如下图。

多线程编程学习笔记——async和await(一)

首先不能在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. &lbrack;Java123&rsqb; JDBC and Multi-Threading 多线程编程学习笔记

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

  8. Java多线程编程&lpar;学习笔记&rpar;

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

  9. python学习笔记 async and await

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

随机推荐

  1. xargs

    xargs的作用一般等同于大多数Unix shell中的反引号,但更加灵活易用,并可以正确处理输入中有空格等特殊字符的情况.对于经常产生大量输出的命令如find.locate和grep来说非常有用.

  2. 《ASP&period;NET1200例》各种类型文件汇总

    aspx是页面文件 ascx是用户控件,用户控件必须嵌入到aspx中才能使用. ascx是用户控件,相当于模板 其实ascx你可以理解为Html里的一部分代码, 只是嵌到aspx里而已, 因为aspx ...

  3. &lbrack;Android Pro&rsqb; Android 打包流程

    Android 打包流程: 官网地址:http://developer.android.com/tools/building/index.html 具体的打包步骤如下: 1:生成R.java类文件:E ...

  4. Ambry&colon; LinkedIn’s Scalable Geo-Distributed Object Store

    https://github.com/linkedin/ambry http://www.open-open.com/lib/view/open1464828607502.html

  5. puppet svn集成

    puppet svn集成

  6. oracle&lowbar;用户与概要文件

    Oracle 用户与概要文件 2012-09-01 15:05:47| 分类: Oracle | 标签:用户与概要文件 |举报 |字号大中小 订阅     用户管理看上去简单其实也是最常出现问题的一个 ...

  7. JDK1&period;8中的线程池

    上面这段代码一直在用,面试的时候也经常被问到,却从未深究过,不知道线程池到底是怎么回事,今天看看源代码,一探其究竟 线程池主要控制的状态是ctl,它是一个原子的整数,其包含两个概念字段: worker ...

  8. 自定义状态栏的颜色及navigation的title颜色

    1.在info.plist中添加View controller-based status bar appearance,值为NO 2.在设置状态栏的地方添加代码 [[UIApplication sha ...

  9. table设置上下左右边距不一样-html

    新手上路,刚刚自学html,仅作为记录学习历程用,有需要的可以参考. 1.边距相同时 <table align="center" cellpadding="15re ...

  10. Typora 配置说明

    目录 Typora 配置说明 贴图功能 自定义快捷键 快捷键使用 Linux下安装typora Typora 配置说明 为了更好的使用markdown,解决markdown中不如Word的不便之处,对 ...