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).在这种方式下,可以通过类似同步方式编写异步代码,极大简 ...
随机推荐
- 2d游戏和 3d游戏的区别
2D游戏和3D游戏的主要区别 一.总结 一句话总结:2D中的单位就是贴图,3D中的单位还有高 1. 3D 和 2D 游戏的区别主要体现在呈现画面和文件体积上: 2. 借助 3D 引擎可以提升 2D 游 ...
- echarts画多条一元回归线
理论上两点一线,只要两个点即可 option = { title: { text: '', left: 'center' }, tooltip: { // trigger: 'item', // fo ...
- Windows Live Wirter
安装: 下载: Windows Live Writer (QQ 里) windows live writer 日志服务器发生问题 更新账户信息 从字面"editPost"我们不难看 ...
- .NET的关于人脸识别引擎分享(C#)
https://www.cnblogs.com/RainbowInTheSky/p/10247921.html
- python3-知识扩展扫盲易忘-map,collections.Counter()的用法
map() 会根据提供的函数对指定序列做映射. 第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表. >> ...
- 如何使用Web3.js API 在页面中进行转账
本文介绍如何使用Web3.js API 在页面中进行转账,是我翻译的文档Web3.js 0.2x 中文版 及 区块链全栈-以太坊DAPP开发实战 中Demo的文章说明. 写在前面 阅读本文前,你应该对 ...
- Confluence 6 给一个从 Jira Service Desk 的非许可证用户访问权限
如果你正在使用 Confluence 为 Jira 服务桌面(Jira Service Desk)的知识库,你可以选择允许所有活动的用户和客户(客户是可以登录的用户,但是这些用户是没有 Conflue ...
- SPL之AccessArray
<?php /** * Class MyArrayAccess * 提供像访问数组一样访问对象的能力的接口 */ class MyArrayAccess implements ArrayAcce ...
- 『TensorFlow』分布式训练_其二_单机多GPU并行&GPU模式设定
建议比对『MXNet』第七弹_多GPU并行程序设计 一.tensorflow GPU设置 GPU指定占用 gpu_options = tf.GPUOptions(per_process_gpu_mem ...
- Django 的逆向解析url--reverse(转)
https://www.cnblogs.com/zhenfei/p/6368955.html Django中提供了一个关于URL的映射的解决方案,你可以做两个方向的使用: 1.有客户端的浏览器发起一个 ...