C#异步编程之async、await

来源:互联网 发布:java游戏开发书籍 编辑:程序博客网 时间:2024/05/17 01:24

async和await这一组关键字是.Net4.5新增的一种异步编程方式,今天就根据自己的理解讲讲async和await与Task之间的关系。

什么是异步

拿操作系统来说,CPU就具有异步性。当在进行IO的耗时操作时,CPU不会处于阻塞状态,而是可以继续执行其它的指令。编程中异步通常用于打开大文件、上传大文件、发起网络请求等耗时操作,异步操作在应用程序主线程以外的其它线程中执行,主线程可以在异步操作时执行其它操作。

异步与同步的区别

同步:同步是指顺序执行,在执行某个操作时,应用程序必须等待其执行完毕后才能执行下一个操作,举个栗子,到了中午的饭点,而我和同事却有一个棘手的bug要处理(改bug很耗时的,顺便吐槽下,玩游戏时经常听到有人把bug当成3个英文字母念成bi you ji),老大要求不改好不能吃饭,这就是一个同步操作,我们想要吃饭,必须先改完bug。
异步:异步是指在执行某个操作时,应用程序可以在执行异步操作时继续执行其它操作,还是用上面的栗子,老大估摸着这个bug改完,食堂早没饭了,就命令我去改bug,然后他跑去吃饭了,即老大在指挥我改bug的时候,并没有要等我改完才去吃饭,而是自己先跑了,这就是异步。

async和await 的用法

用async和await实现异步编程时,需知以下几点:

  1. 异步方法需用async关键字描述,且返回类型只能是void、Task、Task ,如果你要执行的异步方法是有返回值的,那么泛型T就定义为你所需返回的类型
  2. await关键字只能在async声明的异步方法中使用,且其挂起的方法返回类型必须是Task或Task.
  3. await 会让当前方法等待其挂起的方法执行完毕后再继续执行当前方法。
    还是结合代码来说明吧:
C#代码using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace TaskTest{    class Program    {        static void Main(string[] args)        {            Console.WriteLine("主线程运行开始:{0}", System.Threading.Thread.CurrentThread.ManagedThreadId);            Test1();            Console.WriteLine("主线程运行结束:{0}", System.Threading.Thread.CurrentThread.ManagedThreadId);            Console.ReadLine();        }        public static async void Test1()        {            Console.WriteLine("执行异步方法Test1开始:{0}",System.Threading.Thread.CurrentThread.ManagedThreadId);            await Test2();            Console.WriteLine("执行异步方法Test1结束:{0}", System.Threading.Thread.CurrentThread.ManagedThreadId);        }        public static async Task Test2()        {            Console.WriteLine("执行异步方法Test2开始:{0}", System.Threading.Thread.CurrentThread.ManagedThreadId);            Task.Run(() => {                for (int i = 0; i < 10; i++)                {                    Console.WriteLine(i + ":线程ID:{0}", System.Threading.Thread.CurrentThread.ManagedThreadId);                }            });            Console.WriteLine("执行异步方法Test2结束:{0}", System.Threading.Thread.CurrentThread.ManagedThreadId);        }    }}

首先用async定义了两个异步方法Test1()和Test2(),在Main方法中调用Test1(),在Test1()中用await挂起了Test1()方法,让其等待Test2()执行完毕后再执行后面的代码,再来看看Test2(),在Test2()中用Task新开了一个任务线程去执行耗时操作,因为Task前面没有使用await关键字,因而不会阻塞Test2()剩余代码的执行,然后线程控制权交给Test1(),Test1()执行完后,线程控制权交给Main方法。
执行结果:
这里写图片描述

现在,我们在Test2()方法中的Task.Run前面加上await关键字,再来看看执行结果:
这里写图片描述
加上await以后,Test2()被挂起,等待Task执行完毕后,才能执行后面的代码,这时候主线程控制权交回给Test1(),而Test1()也被挂起,等待Test2()执行完毕,所以主线程控制权交回给Main方法,从结果上的线程ID可以看出有两个线程在并发处理,这里不要被结果中的打印顺序迷惑,并不是Test2()中的循环执行完毕后才把控制权交回给主线程,我们把i的值设大一点就知道了
这里写图片描述,线程7和线程10属于并发执行。

从上面的代码可以看到,async和await实现异步编程与Task密不可分,下一篇在Mark下Task。
个人理解,若有偏差,请指正

0 0
原创粉丝点击