最近看了一些园友们写的有关于异步的文章,受益匪浅,写这篇文章的目的是想把自己之前看到的文章做一个总结,同时也希望通过更加通俗易懂的语言让大家了解"异步"编程。

1:什么是异步

  应用程序在启动后,会产生一个进程,进程是构成应用程序资源的集合。在进程内部有称之为线程的对象,线程才是真正负责执行运行命令的。

  线程:

    1:默认情况下,一个应用程序只会有一个线程,从程序开始到结束。

    2:一个进程如果有多个线程,那么多个线程将会共享进程内的资源。

    3:线程不是派生于不同的线程。

  一般来说,我们写的程序都是单线程的,但是这种程序对用户体验很不好,拿WinFrom来说,假设在单线程的情况下,用户点击某个Button执行了一个耗时操作,那么在此操作执行完成前,窗体程序是无法拖动位置的,简单来说,如果这个时候你去操作这个应用程序,那么这个应用程序的状态就会变成:未响应。造成这种问题的最根本原因是这个程序一直都是在单线执行,如果其中某个步骤耗时过长,那么后面的操作只有等待。这种写法不仅浪费资源而且还严重影响性能。而异步则可以帮我们很好的解决这一问题.

2:初识异步

  大壮是个好男人,每天晚上回家后都会煮饭,洗菜,炒菜,然后等饭熟开始吃饭,这几个步骤如果按照单线程处理方式如下:

  

 static void Main(string[] args)
{
var stopWatch = new Stopwatch();
stopWatch.Start();
Console.WriteLine("大壮开始煮饭......");
System.Threading.Thread.Sleep(); //模拟耗时5秒
Console.WriteLine("饭煮熟了开始洗菜......");
System.Threading.Thread.Sleep(); //模拟耗时3秒
Console.WriteLine("菜洗好了,开始炒菜.......");
System.Threading.Thread.Sleep(); //模拟耗时3秒
Console.WriteLine($"开始吃饭,做饭总耗时{stopWatch.ElapsedMilliseconds}");
stopWatch.Start();
Console.ReadLine();
}

  其运行结果如下:

    

  虽然大壮把饭菜做好了,但是他的老婆不愿意了,开始说他:你说你是不是傻啊,你为什么非要等饭煮熟了采取洗菜炒菜呢?为什么就不能把饭煮了后就去洗菜炒菜,然后在等饭熟呢?大壮一拍脑袋,对啊,说改咋就改:

  

 static void Main(string[] args)
{
var stopWatch = new Stopwatch();
stopWatch.Start();
Console.WriteLine("大壮开始煮饭......");
var isEat = CookriceAsync();
Console.WriteLine("饭煮熟了开始洗菜......");
Thread.Sleep(); //模拟耗时3秒
Console.WriteLine("菜洗好了,开始炒菜.......");
Thread.Sleep(); //模拟耗时3秒
if (isEat.Result)
Console.WriteLine($"开始吃饭,做饭总耗时{stopWatch.ElapsedMilliseconds}");
stopWatch.Stop();
Console.ReadLine();
} private static async Task<bool> CookriceAsync()
{
await Task.Run(() =>
{
Thread.Sleep();//模拟耗时5秒;
});
return true; }

异步执行

  其结果运行如下:

  

  通过上面的例子我们不难发现程序运行所耗时明显变短,其运行结果是还是一样的。当程序在执行方的时候,如果碰到异步方法,程序则会跳出异步方法继续执行没有执行的命令,异步方法的执行不会停止。当遇到异步对象点Result的时候,如果异步程序没有执行完,那么Result方法会一直阻塞程序的运行,直到其异步方法执行完毕。

3:初探async/await

  对比未使用异步和使用异步后的代码我们不难发现,我们把做饭的步骤封装成了一个CookriceAsync方法,但是该方法申明出多了一个async,并且返回结果明明是bool却变成了Task<bool>,而且代码中还冒出一个await,why?它们都是干嘛用的?别急,且听我一一道来。

  先说下异步方法的声明:

       (1)关键字:方法头使用 async 修饰。
       (2)要求:包含 N(N>0) 个 await 表达式(不存在 await 表达式的话 IDE 会发出警告),表示需要异步执行的任务。【备注】感谢 czcz1024 的修正与补充:没有的话,就和普通方法一样执行了。
       (3)返回类型:只能返回 3 种类型(void、Task 和 Task<T>)。Task 和 Task<T> 标识返回的对象会在将来完成工作,表示调用方法和异步方法可以继续执行。
       (4)参数:数量不限。但不能使用 out 和 ref 关键字。
       (5)命名约定:方法后缀名应以 Async 结尾。
       (6)其它:匿名方法和 Lambda 表达式也可以作为异步对象;async 是一个上下文关键字;关键字 async 必须在返回类型前。

  异步方法可分成三部分:

       (1)调用方法:在方法调用异步方法,然后在异步方法执行其任务的时候继续执行;
       (2)异步方法:该方法异步执行工作,然后立刻返回到调用方法;
       (3)await 表达式:用于异步方法内部,指出需要异步执行的任务。一个异步方法可以包含多个 await 表达式(不存在 await 表达式的话 IDE 会发出警告)。

  

  关于 async 关键字:

    ①在返回类型之前包含 async 关键字

    ②它只是标识该方法包含一个或多个 await 表达式,即,它本身不创建异步操作。

    ③它是上下文关键字,即可作为变量名。

  

 现在先来简单分析一下这三种返回值类型:void、Task 和 Task<T>

  1:Task<T>:调用方法要从调用中获取一个 T 类型的值,异步方法的返回类型就必须是Task<T>。调用方法从 Task 的 Result 属性获取的就是 T 类型的值。

  2:Task:不需要返回任何结果,但是需要知道异步方法的状态。不过就算方法内含有return语句,也不会返回任何东西。

  3:Void:调用方法执行异步方法,但又不需要做进一步的交互。

本文大部分文字内容来源于:http://www.cnblogs.com/liqingwen/p/5831951.html 写得不错,本篇文章只是进行一些总结。

我也来说说C#中的异步:async/await的更多相关文章

  1. Python 进阶 异步async/await

    一,前言 本文将会讲述Python 3.5之后出现的async/await的使用方法,我从上看到一篇不错的博客,自己对其进行了梳理.该文章原地址https://www.cnblogs.com/dhcn ...

  2. 异步 async & await

    1 什么是异步 异步的另外一种含义是计算机多线程的异步处理.与同步处理相对,异步处理不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其它线程将处理完成,并回调通知此线程. 2 异步场景 l  不 ...

  3. 异步async/await简单应用与探究

    感谢Marco CAO指出的两点错误,已做出修改与补充 异步函数(async/await)简单应用 .NET Framework4.5提供了针对异步函数语法糖,简化了编写异步函数的复杂度. 下面通过一 ...

  4. .Net Core异步async/await探索

    走进.NetCore的异步编程 - 探索 async/await 前言: 这段时间开始用.netcore做公司项目,发现前辈搭的框架通篇运用了异步编程方式,也就是async/await方式,作为一个刚 ...

  5. .Net Core中无处不在的Async/Await是如何提升性能的?

    一.简介 Async/Await在.Net Core中真的是无处不在,到处都是异步操作,那为什么要用?有什么作用?别人说能提升性能?网上一堆文章看的绕晕了也没说清楚, 所以这里从理论,实践,原理一个个 ...

  6. C#Framework4.0支持异步async/await语法

    由于用户使用的是XP系统,但是程序里异步都是通过async/await代码来实现的,然而async/await需要Framework4.5版本才可以,而XP系统最高只能支持到Framework4.0, ...

  7. C#异步中的Task,async,await

    class Program { static void Main(string[] args) { Console.WriteLine("我是主线程,线程ID:{0}", Thre ...

  8. 请教 C# 异步 async await 问题

    各位园友,之前对C#异步只是肤浅了解,请教一个具体问题. 需求: 前台会发送一个Array,这个数组都是 id的集合,比较大.分两步,首先保存这些id,然后去调用异步方法. 可以正常返回json,也可 ...

  9. 简单的node爬虫练手,循环中的异步转同步

    简单的node爬虫练手,循环中的异步转同步 转载:https://blog.csdn.net/qq_24504525/article/details/77856989 看到网上一些基于node做的爬虫 ...

随机推荐

  1. poj 2653 计算几何

    #include <iostream> #include <cstring> #include <algorithm> #include <cmath> ...

  2. verilog中读取文件中的字符串_modelsim高级仿真

    今天给个程序大家玩玩.因为今天遇到一个问题,就是要向UART发送指令,指令非常多,都是字符串.一直copy 函数 UART ("COMM_1");  UART ("COM ...

  3. js 中的bind函数

    bind是Function.prototype中内置函数 作用是指定函数作用域 代码参考 http://blog.csdn.net/load_life/article/details/7200381 ...

  4. 自己动手写List集合(C#)

    平时经常使用微软的List集合,觉得理所应当,这阵子突然意识到学编程学这么久,总不能只生存在某个平台某种语言下面.我觉得要跳出这个框,而数据结构是经常用到的,所以呢,作为一个有志向的程序员应该学会它. ...

  5. php文件链接数据库基本代码

    <?php $conn=@mysql_connect("localhost","root",""); if($conn==null) ...

  6. Node Node

    http://www.nodejs.org/ http://outofmemory.cn/code-snippet/1403/node-javascript-classic-introduction- ...

  7. QT 自动获取可用串口

    本来想直接用Settings来获取的,但是串口信息类似 "\Device\Serial0",死活获取不了,用了转义.反斜杠还是获取不到,所以就放弃了,网上好像也没有获取成功的. 所 ...

  8. HashMap和HashTable 学习

    1. HashMap 1)  hashmap的数据结构 Hashmap是一个数组和链表的结合体(在数据结构称“链表散列“),如下图示: 当我们往hashmap中put元素的时候,先根据key的hash ...

  9. LeetCode——Combinations

    Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For exampl ...

  10. SQL中的Update、delete与inner join 联合使用

    Update XXX set XXX where 这种写法大家肯定都知道,才发现update和delete居然支持inner join的update方式,太神奇了. update的格式是 update ...