c# 关于async/await异步编程的浅析和使用
线程的同步运行,时效性慢,异步运行,时效性快!
在c#5.0引出了async/await关键字,可以用其来进行异步编程。
async/await定义异步方法的语法如下:
1、在方法的返回类型前面加上async关键字;
2、返回类型固定为void、Task和Task<T>。返回类型建议用Task或Task<T>,因为void不方便捕获异常;
3、形参不能使用out和ref关键字;
4、在方法体内,需要包含1到多个await表达式,每一个表示需要异步执行的任务;
5、方法名的后缀一般约定加上Async。
//返回Task的异步方法示例:
public static async Task DownLoadDataAsync() {
var wc = new WebClient();
var result = await wc.DownloadStringTaskAsync(@"http://www.baidu.com");
} //返回Task<T>的异步方法示例:
public static async Task<String> DownLoadDataAsync() {
var wc = new WebClient();
var result = await wc.DownloadStringTaskAsync(@"http://www.baidu.com"); return result;
}
备注:Task关键字表示任务调度,一般以异步的方式执行。如果async异步方法需要返回数据,则其返回类型使用Task<T>的方式,类型T就是真正需要返回的参数类型,而异步方法执行完毕后会将需要返回的参数存储在Task变量中。
说到异步执行,到底在哪一步才进行了异步执行?这就引出了await关键字。请看下面的代码:
class Program {
static void Main(string[] args) {
Task<String> task = DownLoadDataAsync();
Console.WriteLine("这是main主线程!");
Console.ReadKey();
}
//返回Task<T>的异步方法示例:
public static async Task<String> DownLoadDataAsync() {
Console.WriteLine("进入异步方法第一步!");
var wc = new WebClient();
Console.WriteLine("进入异步方法第二步!");
var result = await wc.DownloadStringTaskAsync(@"http://www.baidu.com");
Console.WriteLine("进入异步方法第三步!");
return result;
}
}
执行结果:

可以看见,在执行异步方法的时候,当程序执行到await时,就开始了异步执行!为何能够异步呢?接下来再测试一下。
static void Main(string[] args) {
Console.WriteLine($"1.main tid:{Thread.CurrentThread.ManagedThreadId}");
DelayAsync();
Console.WriteLine($"2.main tid:{Thread.CurrentThread.ManagedThreadId}");
Console.ReadKey();
}
private static async Task DelayAsync() {
Console.WriteLine($"1.DelayAsync tid:{Thread.CurrentThread.ManagedThreadId}");
await Task.Delay().ContinueWith(t => {
Console.WriteLine($"2.DelayAsync tid:{Thread.CurrentThread.ManagedThreadId}");
});
Console.WriteLine($"3.DelayAsync tid:{Thread.CurrentThread.ManagedThreadId}");
await Task.Delay().ContinueWith(t => {
Console.WriteLine($"4.DelayAsync tid:{Thread.CurrentThread.ManagedThreadId}");
});
Console.WriteLine($"5.DelayAsync tid:{Thread.CurrentThread.ManagedThreadId}");
}
程序执行结果:

原来是到了await这个关键字时,程序单独开辟了一个线程去执行await后的代码,而后执行步骤直接返回到主线程调用异步方法后一步!
如何在main主线程执行完毕之前获取异步方法的返回结果?这就要用到Task的Wait()方法!
Task.Wait()方法的功能是等待当前这个异步任务执行完毕。相当于阻塞了主线程的继续执行,直到异步方法执行完毕,主线程才可继续执行。这就是为何异步方法的返回类型为Task的原因!
static void Main(string[] args) {
Task<String> task = DownLoadDataAsync();
task.Wait();
Console.WriteLine("这是main主线程!");
Console.ReadKey();
}
执行结果:

c# 关于async/await异步编程的浅析和使用的更多相关文章
- 【转】C# Async/Await 异步编程中的最佳做法
Async/Await 异步编程中的最佳做法 Stephen Cleary 近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支 ...
- .NET Web应用中为什么要使用async/await异步编程
前言 什么是async/await? await和async是.NET Framework4.5框架.C#5.0语法里面出现的技术,目的是用于简化异步编程模型. async和await的关系? asy ...
- C#中 Thread,Task,Async/Await 异步编程
什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调 ...
- async/await 异步编程(转载)
转载地址:http://www.cnblogs.com/teroy/p/4015461.html 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入 ...
- async/await 异步编程
前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入的,由于之前对于异步编程不是很了解,所以花费了一些时间学习一下相关的知识,并整理成这篇博客,如果在 ...
- c# async/await异步编程死锁的问题
在异步编程中,如果稍有不注意,就会造成死锁问题.何为死锁:即两个以上的线程同时争夺被互相锁住的资源,两个都不放手. 在UI或asp.net中,容易造成死锁的代码如下所示: private void b ...
- .NET 中的 async/await 异步编程
原文出处: Teroy 的博客 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入的,由于之前对于异步编程不是很了解,所以花费了一些时间学习一下相关 ...
- Async await 异步编程说明
希望在编程上有些许提高所以 最近连续2篇博客都在说明多线程和异步编程的使用,异步和多线程之间区别请自行百度,因为理解不是特别透彻就不在叙述以免误导大家,这里写下新研究整理 task 和 await ...
- ASP.Net中的async+await异步编程
在.NET Framework4.5框架.C#5.0语法中,通过async和await两个关键字,引入了一种新的基于任务的异步编程模型(TAP).在这种方式下,可以通过类似同步方式编写异步代码,极大简 ...
随机推荐
- Codeforces 838 B - Diverging Directions
B - Diverging Directions 思路: 用dfs序+线段树维护子树中距离(从1到u,再从u到1)的最小值 代码: #pragma GCC optimize(2) #pragma GC ...
- reactiveCocoa使用
@代理 简介:使用RACSubject信号替换 控制器2的操作: <1在头文件定义一个信号: @property (nonatomic, strong) RACSubject *delegate ...
- lombok插件:Data自动get/set方法, Slf4j实现Logger的调用
lombok插件:Data自动get/set方法, Slf4j实现Logger的调用 lombok.Data import lombok.Data; import org.hibernate.anno ...
- rabbimq
问题 启动RabbitMQ后,没法访问Web管理页面 解决 RabbitMQ安装后默认是不启动管理模块的,所以需要配置将管理模块启动 启动管理模块命令如下 rabbitmqctl start_ ...
- 小程序授权demo
<button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo=" ...
- python中for循环的底层实现机制 迭代
在python中,存在2种循环方式:for循环和while循环. while循环的实现很简单, 其本质就是一个条件语句,自定义条件,当条件满足的时候,不断执行while代码块. 但是for循环,究竟是 ...
- 6月16 ThinkPHP连接数据库及Model数据模型层--------查询及数据添加
连接数据库配置及Model数据模型层 convertion.php config.php 1.在config.php做数据库连接配置 2.修改配置 /* 数据库设置 */ 'DB_TYPE' => ...
- python-flask-SQLAlchemy-Utils组件
SQLAlchemy-Utils,提供choice功能 定义: # pip3 install sqlalchemy-utils from sqlalchemy_utils import ChoiceT ...
- leetcode-algorithms-20 Valid Parentheses
leetcode-algorithms-20 Valid Parentheses Given a string containing just the characters '(', ')', '{' ...
- oracle数据库静态监听配置示例
[oracle@Oracle11g admin]$ cat listener.ora SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOB ...