1.简介
在说到异步前,先来理一下几个容易混淆的概念,并行、多线程、异步。
并行,一般指并行计算,是说同一时刻有多条指令同时被执行,这些指令可能执行于同一CPU的多核上,或者多个CPU上,或者多个物理主机甚至多个网络中。
多线程,一般指同一进程中多个线程(包含其数据结构、上下文与代码片段)协作运行。在多核计算机中多个线程将有机会同时运行于多个核上,如果线程中进行的是计算,则行成并行计算。
异步,与同步相对应,是指呼叫另一操作后,不等待其结果,继续执行之后的操作,若之后没有其他操作,当前线程将进入睡眠状态,而CPU时间将有机会切至其他线程。在异步操作完成后通过回调函数的方式获取通知与结果。异步的实现方式有多种,如多线程与完成端口。多线程将异步操作放入另一线程中运行,通过轮询或回调方法得到完成通知;完成端口,由操作系统接管异步操作的调度,通过硬件中断,在完成时触发回调方法,此方式不需要占用额外线程。
本文讨论.NET下的异步,以及其进化过程中出现的多种异步模式。
2.同步

public void Main() { Stopwatch stopwatch=new Stopwatch(); stopwatch.Start(); MainMethod(); ElapsedtimeMethod(); stopwatch.Stop(); var result = stopwatch.ElapsedMilliseconds; Console.WriteLine(result); } public void MainMethod() { Thread.Sleep(1000); } /// <summary> /// 耗时方法:模拟耗时操作,例如IO,Http等 /// </summary> /// <returns></returns> public void ElapsedtimeMethod() { Thread.Sleep(3000); }
结果是4秒多
3.异步
3.1 Thread时代

public void Main() { Stopwatch stopwatch=new Stopwatch(); stopwatch.Start(); //开启两个线程 Thread mainThread=new Thread(MainMethod); Thread elapTread=new Thread(ElapsedtimeMethod); mainThread.Start(); elapTread.Start(); //阻塞两个线程,等待两个线程全部执行完毕 mainThread.Join(); elapTread.Join(); stopwatch.Stop(); var result = stopwatch.ElapsedMilliseconds; Console.WriteLine(result); } public void MainMethod() { Thread.Sleep(1000); } /// <summary> /// 耗时方法:模拟耗时操作,例如IO,Http等 /// </summary> /// <returns></returns> public void ElapsedtimeMethod() { Thread.Sleep(3000); }
结果是:3秒多点,此处只是简介,如果您对TreadPool等感兴趣请自己在园子里搜。
3.2 Task时代

public void Main() { Stopwatch stopwatch=new Stopwatch(); stopwatch.Start(); var task1 = Task.Run(() => { Task1(); }); var task2 = Task.Run(() => { Task2(); }); task1.Wait(); task2.Wait(); stopwatch.Stop(); var result = stopwatch.ElapsedMilliseconds; Console.WriteLine(result); } public void Task1() { Task.Delay(2000); } public void Task2() { Task.Delay(4000); }
结果是:4秒
3.3 Asnyc await时代

[TestMethod] public async Task Main() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); await Task1(); await Task2(); stopwatch.Stop(); var result = stopwatch.ElapsedMilliseconds; Console.WriteLine(result); } [TestMethod] public async Task Main1() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); var a=Task1(); var b=Task2(); await a; await b; stopwatch.Stop(); var result = stopwatch.ElapsedMilliseconds; Console.WriteLine(result); } public async Task Task1() { await Task.Delay(2000); } public async Task Task2() { await Task.Delay(4000); }
Main结果是6;Main1结果是4;原因就不用说了吧;哈哈 Main相当于同步。