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

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. Dokcer 组成原理简介

    首先来张图了解Docker的组成 重要 Docker在启动容器的时候,需要创建文件系统,为rootfs提供挂载点.最初Docker仅能在支持Aufs文件系统的Linux发行版上运行,但是由于Aufs未 ...

  2. iOS开发项目名称修改

    前言:在IOS开发中,有时候想改一下项目的名字,都会遇到很多麻烦.直接改项目名吧,XCODE又不会帮你改所有的名字.总是有很多文件.文件夹或者是项目设置的项.而且都是不能随便改的,有时候改着改着,编译 ...

  3. Windows Azure 网站自愈

    编辑人员注释:本文章由 Windows Azure 网站团队的项目经理Apurva Joshi 撰写. 您有多少次在半夜被叫醒去解决一个仅需重新启动网站即可解决的问题?要是可以自动检测一些状况并自动恢 ...

  4. hdoj 2544 最短路(最短路+Dijkstrea算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 思路分析:该问题给定一个无向图,要求求从起始点到终点的最短路径长度:可以使用dijkstra算法 ...

  5. makinacorpus/spynner

    makinacorpus/spynner Intro Contents Intro Credits Companies Authors Contributors Dependencies Feedba ...

  6. CF 191 div2

    A.数据量很小,直接爆搞. #include <iostream> #include <cstdio> #include <algorithm> #include ...

  7. Android ScrollView嵌套HorizontalScrollView 滑动问题 ScrollView包括GridView显示问题

    今天项目使用到ScrollView嵌套HorizontalScrollView,ScrollView里包括GridView,发现几个问题非常经典.在此记录: 问题1.ScrollView嵌套Horiz ...

  8. Enze Second day

    哈喽,很高兴在云和学院又学了一天的新知识,现在,我来继续总结一下今天所学的以及对昨天的一些补充. 变量 • 声明变量的语法格式: –数据类型  变量名; •赋值:     变量名=值; 变量的命名 • ...

  9. Visual Studio Tools for Unity安装及使用

    Visual Studio Tools for Unity安装及使用 转载自:CSDN 晃了一下,10.1到现在又过去两个月了,这两个月什么也没有学,整天上班下班,从这周末开始拾起unity,为了年后 ...

  10. memcache学习使用

    一.安装 二.telnet测试 启动:memcached -d -m 120.24.242.100 -p 11211 -u root 测试:telnet localhost 11211 >> ...