【转】谈谈c#中异步编程模型的变迁**
大家在編程過程中都會用到一些異步編程的情況。在c#的BCL中,很多api都提供了異步方法,初學(xué)者可能對各種不同異步方法的使用感到迷惑,本文主要為大家梳理一下異步方法的變遷以及如何使用異步方法。
BeginXXX,EndXXX模式
在.Net Framework 2.0中,最常見的方法是BeginXXX,和EndXXX這樣的方法來搭配使用。這種模式可以概括為方法+回調(diào)函數(shù)模式或者稱為InvokeMethod+EventHandler模式。
這種模型的基本流程是:
我們看一個FileStream的示例方法,在.Net 2.0中,你需要這樣使用異步:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using?System; using?System.IO; using?System.Text; ? public?class?AsyncTest { ????public?static?void?Main(string[] args) ????{ ????????using?(FileStream file =?new?FileStream("Test.txt", FileMode.OpenOrCreate)) ????????{ ????????????var?bytes = Encoding.UTF8.GetBytes("Test for .net framework 2.0"); ? ????????????IAsyncResult asyncResult = file.BeginWrite(bytes, 0, bytes.Length, callback,?null); ? ????????????file.EndWrite(asyncResult); ????????} ? ????????Console.ReadLine(); ????} ? ????private?static?void?callback(IAsyncResult ar) ????{ ????????Console.WriteLine("Finish Write"); ????} } |
XXXAsync模式
從.Net 4.0開始,微軟引入了Task。由于Task本身的靈活性,也使得我們的異步編程模型更簡潔。上面的例子在.Net 4.5中可以這樣實現(xiàn):
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | using?System; using?System.IO; using?System.Text; using?System.Threading.Tasks; ? public?class?AsyncTest { ????public?static?void?Main(string[] args) ????{ ????????using?(FileStream file =?new?FileStream("Test.txt", FileMode.OpenOrCreate)) ????????{ ????????????var?bytes = Encoding.UTF8.GetBytes("Test for .net framework 4.5"); ? ????????????var?task = file.WriteAsync(bytes, 0, bytes.Length); ? ????????????task.Wait(); ????????} ? ????????Console.ReadLine(); ????} } |
微軟在許多BCL的api中都添加了XXXAsync方法來實現(xiàn)新的異步模型。Task本身比回調(diào)方法靈活了許多,可以更優(yōu)雅的實現(xiàn)回調(diào),取消,調(diào)度等操作。關(guān)于Task的使用方式可以看我之前總結(jié)的文章link。
async和await模型
為了進一步簡化異步模型,微軟從Visual Studio 2012開始引入了async和await關(guān)鍵字。這個模型本身是基于編譯器的一個語法糖,編譯后會生成一個statemachine模型。這樣上面例子中的寫法也可以簡化成:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | using?System; using?System.IO; using?System.Text; using?System.Threading.Tasks; ? public?class?AsyncTest { ????public?static?void?Main(string[] args) ????{ ????????TestFunc(); ????} ? ????private?static?async?void?TestFunc() ????{ ????????using?(FileStream file =?new?FileStream("Test.txt", FileMode.OpenOrCreate)) ????????{ ????????????var?bytes = Encoding.UTF8.GetBytes("Test for .net framework 4.5"); ????????????await file.WriteAsync(bytes, 0, bytes.Length); ????????} ????} } |
關(guān)于異步編程模型的兼容性
如果大家注意看BCL中的類庫,會發(fā)現(xiàn)微軟并沒有在最新版本的類庫中對每一個BeginXXX的方法都添加了XXXAsync方法。這種情況下我們?nèi)绾文茏屝碌漠惒侥P图嫒菖f的方法呢?
以NamedPipeServerStream為例,這個類庫實現(xiàn)了一個管道的功能,微軟并沒有為其更新XXXAsync方法,你可以使用TaskFactory來兼容新的異步模型,你可以這樣來實現(xiàn):
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | private?static?void?OldAsyncModel() { ????NamedPipeServerStream pipe =?new?NamedPipeServerStream("customPipe", PipeDirection.InOut, -1, PipeTransmissionMode.Message, PipeOptions.Asynchronous | PipeOptions.WriteThrough); ????IAsyncResult async = pipe.BeginWaitForConnection(callback,?null); ????pipe.EndWaitForConnection(async); } ? private?static?async?void?NewAsyncModel() { ????NamedPipeServerStream pipe =?new?NamedPipeServerStream("customPipe", PipeDirection.InOut, -1, PipeTransmissionMode.Message, PipeOptions.Asynchronous | PipeOptions.WriteThrough); ? ????await Task.Factory.FromAsync(pipe.BeginWaitForConnection, pipe.EndWaitForConnection,?null); } |
因此,我們可以總結(jié)為,.Net中有兩種異步編程模型:
BeginXXX模型微軟已經(jīng)逐漸的考慮廢棄,返回Task的異步編程模型目前是微軟建議的方式。
??
作者:獨上高樓
出處:http://www.cnblogs.com/myprogram/
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
總結(jié)
以上是生活随笔為你收集整理的【转】谈谈c#中异步编程模型的变迁**的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转】文本文件和二进制文件区别及java
- 下一篇: 神舟十四号的第一支vlog出炉:三人组已