线程的同步运行,时效性慢,异步运行,时效性快!

在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异步编程的浅析和使用的更多相关文章

  1. 【转】C# Async/Await 异步编程中的最佳做法

    Async/Await 异步编程中的最佳做法 Stephen Cleary 近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支 ...

  2. .NET Web应用中为什么要使用async/await异步编程

    前言 什么是async/await? await和async是.NET Framework4.5框架.C#5.0语法里面出现的技术,目的是用于简化异步编程模型. async和await的关系? asy ...

  3. C#中 Thread,Task,Async/Await 异步编程

    什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调 ...

  4. async/await 异步编程(转载)

    转载地址:http://www.cnblogs.com/teroy/p/4015461.html 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入 ...

  5. async/await 异步编程

    前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入的,由于之前对于异步编程不是很了解,所以花费了一些时间学习一下相关的知识,并整理成这篇博客,如果在 ...

  6. c# async/await异步编程死锁的问题

    在异步编程中,如果稍有不注意,就会造成死锁问题.何为死锁:即两个以上的线程同时争夺被互相锁住的资源,两个都不放手. 在UI或asp.net中,容易造成死锁的代码如下所示: private void b ...

  7. .NET 中的 async/await 异步编程

    原文出处: Teroy 的博客 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入的,由于之前对于异步编程不是很了解,所以花费了一些时间学习一下相关 ...

  8. Async await 异步编程说明

    希望在编程上有些许提高所以 最近连续2篇博客都在说明多线程和异步编程的使用,异步和多线程之间区别请自行百度,因为理解不是特别透彻就不在叙述以免误导大家,这里写下新研究整理 task  和 await ...

  9. ASP.Net中的async+await异步编程

    在.NET Framework4.5框架.C#5.0语法中,通过async和await两个关键字,引入了一种新的基于任务的异步编程模型(TAP).在这种方式下,可以通过类似同步方式编写异步代码,极大简 ...

随机推荐

  1. (转)C# Delegate.Invoke、Delegate.BeginInvoke

    Delegate的Invoke.BeginInvoke 1.Delegate.Invoke (委托同步调用) a.委托的Invoke方法,在当前线程中执行委托. b.委托执行时阻塞当前线程,知道委托执 ...

  2. c# 读取txt方法

    string strLine; try { FileStream aFile = new FileStream("Log.txt", FileMode.Open); StreamR ...

  3. PC端、移动端的页面适配及兼容处理

    转自 一.关于移动端兼容性 目前针对跨终端的方案,主要分为两大阵营:一套资源Vs两套资源. 第一种是通过响应式或页面终端判断去实现一套资源适配所有终端: 第二种是通过终端判断分别调取两套资源以适配所有 ...

  4. HeadFirst Ruby 第七章总结 references

    前言 这一章的内容关于 references,讲了当 Ruby 程序中可能会遇到关于 reference 与 object 之间概念混淆而导致的问题. 导言 本章从一个 astronomer 发现 s ...

  5. Java 发送SOAP请求调用WebService,解析SOAP报文

    https://blog.csdn.net/Peng_Hong_fu/article/details/80113196 记录测试代码 SoapUI调用路径 http://localhost:8082/ ...

  6. request.POST 和 request.GET

    通过request.POST属性   得到<提交的表单数据>,也是一个类字典对象.request.GET属性 ,得到<URL中的keyvalue请求参数>,也是一个类字典对象.

  7. c# 正则表达式如何处理换行符?

    我们要分析网页,把整个网页内容作为匹配源,但是c#的正则表达式是默认以一行为单位的,使用 RegexOptions.Multiline 也没有实质性作用(它知识改变了^和$的行为) 只要在正则表达式前 ...

  8. 将内网ip映射到外网域名

     一.应用场景 1.在本地测试微信支付回调 二.如何使用natapp实现内网穿透 1.第一步注册账号并进行实名制认证 natapp网站地址 https://natapp.cn/ 2.第二步申请免费隧道 ...

  9. VS Code行内样式提示插件

    打开vscode,在软件界面左下角找到“齿轮”标志并点击,在弹出的菜单中选择“设置”,把下面的代码添加到设置里. { "workbench.colorTheme": "C ...

  10. 『C++』基础知识点

    一.基础知识 1.C++编译流程 以Unix系统编译中间文件为说明: .cpp—(编译预处理)—>.ii—(编译)—>.s—(汇编)—>.o—(ld,连接)—>.out 2.# ...