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).在这种方式下,可以通过类似同步方式编写异步代码,极大简 ...
随机推荐
- Unity--- 资源路径问题
使用 System.IO.Path 这个API得到的路径,其实也是以"\"分隔路径的. 我们在windows下打开资源管理器,某个目录或文件的路径为:E:\uniuProject5 ...
- C# DataTable 通过Linq分组
datatable我们是经常使用到的,但是需要对数据进行分组,具体代码如下: var result = dt.AsEnumerable().GroupBy(f => new { type = f ...
- LeetCode--005--最长回文子串(java)
给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: &qu ...
- POJ-3693/HDU-2459 Maximum repetition substring 最多重复次数的子串(需要输出具体子串,按字典序)
http://acm.hdu.edu.cn/showproblem.php?pid=2459 之前hihocoder那题可以算出最多重复次数,但是没有输出子串.一开始以为只要基于那个,每次更新答案的时 ...
- linux+vs2013编译静态库和动态库
Linux下创建与使用静态库 Linux静态库命名规则 Linux静态库命名规范,必须是"lib[your_library_name].a":lib为前缀,中间是静态库名,扩展名为 ...
- php 常用设计模式demo
<?php//__get()//__set()当对象中属性不存在时调用该魔术方法//__call()当对象中方法不存在时//__callStatic()静态方法//__string()当对象不能 ...
- Lowest Common Ancestor of a Binary Search Tree(Java 递归与非递归)
题目描述: Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in ...
- SWUST OJ(952)
单链表的插入操作实现 #include <stdio.h> #include <stdlib.h> typedef struct LinkList { int data; st ...
- js事件流 事件捕获 及时间冒泡详解
Javascript与HTML之间的交互是通过事件实现. 一.事件流 事件,是文档或浏览器窗口中发生的一些特定的交互瞬间.事件流,描述的是页面中接受事件的顺序.IE9,chrome,Firefox,O ...
- jackson实体转json时 为NULL不参加序列化的汇总
首先加入依赖 <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson ...