C#异步编程之async、await

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
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值