我为什么喜欢用C#来做并发编程
生活随笔
收集整理的這篇文章主要介紹了
我为什么喜欢用C#来做并发编程
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題記:就語言和運行時層面,C#做并發(fā)編程一點都不弱,缺的是生態(tài)和社區(qū)。
硅谷才女朱赟(我的家門)昨天發(fā)了一篇文章《為什么用 Java —— 關(guān)于并發(fā)編程》,讓大家學(xué)習(xí)了Java中如何進行并發(fā)編程的一些基本知識。作為一個將近15年的.NET程序員,我覺得有必要給大家補充介紹一下C#進行并發(fā)編程的知識(當(dāng)然不會太深入講解)。這篇文章無意進行技術(shù)比較,畢竟技術(shù)只是工具(大同小異,各有千秋),主要還是看用工具的人。
并發(fā)(英文Concurrency),其實是一個很泛的概念,字面意思就是“同時做多件事”,不過方式有所不同。在.NET的世界里面,并發(fā)一般涉及如下幾個方面:
多線程編程(已過時,不介紹) 異步編程 并行編程 響應(yīng)式編程 數(shù)據(jù)流編程
如果使用回調(diào)或事件來實現(xiàn)(容易callback hell),不僅編寫這樣的代碼不直觀,很快就容易把代碼搞得一團糟。不過在.NET 4.5(C# 5)中引入的async/await關(guān)鍵字(在.NET 4.0中通過添加Microsoft.Bcl.Async包也可以使用),讓編寫異步代碼變得容易和優(yōu)雅。通過使用async/await關(guān)鍵字,可以像寫同步代碼那樣編寫異步代碼,所有的回調(diào)和事件處理都交給編譯器和運行時幫你處理了。
使用異步編程有兩個好處:不阻塞主線程(比如UI線程),提高服務(wù)端應(yīng)用的吞吐量。所以微軟推薦ASP.NET中默認使用異步來處理請求。
要詳細了解異步編程,可以參考官方文檔:https://msdn.microsoft.com/en-us/library/jj152938(v=vs.110).aspx 和《Async in C# 5.0》這本書。另外,在這個官方文檔中,微軟還特意把異步編程分作了3種不同的模型:基于任務(wù)的模式(TAP)就是我上面推薦的這種,基于事件的模式(EAP)和異步編程模型(APM)我上面不推薦的事件和回調(diào)。
在.NET中,并行的支持主要靠.NET 4.0引入的任務(wù)并行庫和并行LINQ。通過這些庫可以實現(xiàn)數(shù)據(jù)并行處理(處理方式相同,輸入數(shù)據(jù)不同,比如我上面提到的應(yīng)用場景)或者任務(wù)并行處理(處理方式不同,且數(shù)據(jù)隔離)。通過使用并行處理庫,你不用關(guān)心Task的創(chuàng)建和管理(當(dāng)然更不用說底層的線程了),只需要關(guān)注處理任務(wù)本身就行了。
具體的用法還是參考官方文檔:https://msdn.microsoft.com/en-us/library/dd460693(v=vs.110).aspx,當(dāng)然《Parallel Programming with Microsoft .NET》這本書也行。
Extensions了。一開始要理解響應(yīng)式編程有點困難,但是一旦理解了,你就會對它的強大功能愛不釋手。簡單來說,響應(yīng)式編程把事件流看作數(shù)據(jù)流,不過數(shù)據(jù)流是從IEnumable中拉取的,而數(shù)據(jù)流是從IObservable推送給你的。為什么響應(yīng)式編程可以實現(xiàn)并發(fā)呢?這是因為Rx做到線程不可知,每次事件觸發(fā),后續(xù)的處理會從線程池中任意取出一個線程來處理。且可以對事件設(shè)置窗口期和限流。舉個例子,你可以用Rx來讓搜索文本框進行延遲處理(而不用類似我很早的時候用個定時器來延遲了)。
要詳細了解Rx最好的方式就是瀏覽 IntroToRx.com 這個網(wǎng)站,當(dāng)然還有官方文檔:https://msdn.microsoft.com/en-us/data/gg577609
望文生義,TPL DataFlow就是對數(shù)據(jù)進行一連串處理,首先為這樣的處理定義一套網(wǎng)格(mesh),網(wǎng)格中可以定義分叉(fork)、連接(join)、循環(huán)(loop)。數(shù)據(jù)流入這樣的處理網(wǎng)格就能夠并行的被處理。你可以認為網(wǎng)格是一種升級版的管道,實際上很多時候就是被當(dāng)作管道來使用。使用場景可以是“分析文本文件中詞頻”,也可以是“處理生產(chǎn)者/消費者問題”。
參考資料當(dāng)然也是官方文檔:https://msdn.microsoft.com/en-us/library/hh228603(v=vs.110).aspx
可用于實現(xiàn)DDD+EventSourcing/CQRS系統(tǒng)。
官方網(wǎng)站是:http://dotnet.github.io/orleans/,善友也有介紹:http://www.cnblogs.com/shanyou/p/4295523.html
那么,我為什么喜歡使用C#來做并發(fā)編程呢?顯而易見,有上面這些唾手可得的工具,使用C#同樣可以輕易開發(fā)并發(fā)程序。
硅谷才女朱赟(我的家門)昨天發(fā)了一篇文章《為什么用 Java —— 關(guān)于并發(fā)編程》,讓大家學(xué)習(xí)了Java中如何進行并發(fā)編程的一些基本知識。作為一個將近15年的.NET程序員,我覺得有必要給大家補充介紹一下C#進行并發(fā)編程的知識(當(dāng)然不會太深入講解)。這篇文章無意進行技術(shù)比較,畢竟技術(shù)只是工具(大同小異,各有千秋),主要還是看用工具的人。
并發(fā)(英文Concurrency),其實是一個很泛的概念,字面意思就是“同時做多件事”,不過方式有所不同。在.NET的世界里面,并發(fā)一般涉及如下幾個方面:
為了支持以上編程,.NET提供了很多基礎(chǔ)功能,比如:委托,匿名函數(shù),Lambda表達式,線程池,Task模型,支持并發(fā)的集合(線程安全集合和不可變集合) ,調(diào)度器,同步功能。在這里,就不對這些內(nèi)容進行介紹了,大家可以自行搜索學(xué)習(xí)。另外,對于Actor模型,.NET中也有支持,但我不認為它屬于語言/運行時層面的并發(fā),它更像架構(gòu)層面的并發(fā),我最后會簡單介紹。
1,異步編程
異步編程就是使用future模式(又稱promise)或者回調(diào)機制來實現(xiàn)(Non-blocking on waiting)。如果使用回調(diào)或事件來實現(xiàn)(容易callback hell),不僅編寫這樣的代碼不直觀,很快就容易把代碼搞得一團糟。不過在.NET 4.5(C# 5)中引入的async/await關(guān)鍵字(在.NET 4.0中通過添加Microsoft.Bcl.Async包也可以使用),讓編寫異步代碼變得容易和優(yōu)雅。通過使用async/await關(guān)鍵字,可以像寫同步代碼那樣編寫異步代碼,所有的回調(diào)和事件處理都交給編譯器和運行時幫你處理了。
使用異步編程有兩個好處:不阻塞主線程(比如UI線程),提高服務(wù)端應(yīng)用的吞吐量。所以微軟推薦ASP.NET中默認使用異步來處理請求。
要詳細了解異步編程,可以參考官方文檔:https://msdn.microsoft.com/en-us/library/jj152938(v=vs.110).aspx 和《Async in C# 5.0》這本書。另外,在這個官方文檔中,微軟還特意把異步編程分作了3種不同的模型:基于任務(wù)的模式(TAP)就是我上面推薦的這種,基于事件的模式(EAP)和異步編程模型(APM)我上面不推薦的事件和回調(diào)。
2,并行編程
并行編程的出現(xiàn)實際上是隨著CPU有多核而興起的,目的是充分利用多核CPU的計算能力。并行編程由于會提高CPU的利用率,更適合客戶端的一些應(yīng)用,對于服務(wù)端的應(yīng)用可能會造成負面影響(因為服務(wù)器本身就具有并行處理的特點,比如IIS會并行的處理多個請求)。我自己使用并行編程最多的場景是之前分析環(huán)境數(shù)據(jù)不確定度的時候,使用并行的方式計算蒙特卡洛模擬(計算上千次之后擬合),當(dāng)然后來我使用泰勒級數(shù)展開來計算不確定度,沒有這么多的計算量就無需并行了。當(dāng)然在計算多方案結(jié)果比較的情況下,還是繼續(xù)使用了并發(fā)計算。在.NET中,并行的支持主要靠.NET 4.0引入的任務(wù)并行庫和并行LINQ。通過這些庫可以實現(xiàn)數(shù)據(jù)并行處理(處理方式相同,輸入數(shù)據(jù)不同,比如我上面提到的應(yīng)用場景)或者任務(wù)并行處理(處理方式不同,且數(shù)據(jù)隔離)。通過使用并行處理庫,你不用關(guān)心Task的創(chuàng)建和管理(當(dāng)然更不用說底層的線程了),只需要關(guān)注處理任務(wù)本身就行了。
具體的用法還是參考官方文檔:https://msdn.microsoft.com/en-us/library/dd460693(v=vs.110).aspx,當(dāng)然《Parallel Programming with Microsoft .NET》這本書也行。
3,響應(yīng)式編程
響應(yīng)式編程最近成為了一個Buzzword,其實微軟6年前就開始給.NET提供一個ReactiveExtensions了。一開始要理解響應(yīng)式編程有點困難,但是一旦理解了,你就會對它的強大功能愛不釋手。簡單來說,響應(yīng)式編程把事件流看作數(shù)據(jù)流,不過數(shù)據(jù)流是從IEnumable中拉取的,而數(shù)據(jù)流是從IObservable推送給你的。為什么響應(yīng)式編程可以實現(xiàn)并發(fā)呢?這是因為Rx做到線程不可知,每次事件觸發(fā),后續(xù)的處理會從線程池中任意取出一個線程來處理。且可以對事件設(shè)置窗口期和限流。舉個例子,你可以用Rx來讓搜索文本框進行延遲處理(而不用類似我很早的時候用個定時器來延遲了)。
要詳細了解Rx最好的方式就是瀏覽 IntroToRx.com 這個網(wǎng)站,當(dāng)然還有官方文檔:https://msdn.microsoft.com/en-us/data/gg577609
4,數(shù)據(jù)流編程
數(shù)據(jù)流(DataFlow)編程可能大家就更陌生了,不過還是有些常用場景可以使用數(shù)據(jù)流來解決。數(shù)據(jù)流其實是在任務(wù)并行庫(TPL)上衍生出來的一套處理數(shù)據(jù)的擴展(也結(jié)合了異步的特性),TPL也是處理并行編程中任務(wù)并行和數(shù)據(jù)并行的基礎(chǔ)庫。望文生義,TPL DataFlow就是對數(shù)據(jù)進行一連串處理,首先為這樣的處理定義一套網(wǎng)格(mesh),網(wǎng)格中可以定義分叉(fork)、連接(join)、循環(huán)(loop)。數(shù)據(jù)流入這樣的處理網(wǎng)格就能夠并行的被處理。你可以認為網(wǎng)格是一種升級版的管道,實際上很多時候就是被當(dāng)作管道來使用。使用場景可以是“分析文本文件中詞頻”,也可以是“處理生產(chǎn)者/消費者問題”。
參考資料當(dāng)然也是官方文檔:https://msdn.microsoft.com/en-us/library/hh228603(v=vs.110).aspx
5,Actor模型
Scala有Akka,其實微軟研究院也推出了Orleans來支持了Actor模型的實現(xiàn),當(dāng)然也有Akka.NET可用。Orleans設(shè)計的目標是為了方便程序員開發(fā)需要大規(guī)模擴展的云服務(wù),可用于實現(xiàn)DDD+EventSourcing/CQRS系統(tǒng)。
官方網(wǎng)站是:http://dotnet.github.io/orleans/,善友也有介紹:http://www.cnblogs.com/shanyou/p/4295523.html
那么,我為什么喜歡使用C#來做并發(fā)編程呢?顯而易見,有上面這些唾手可得的工具,使用C#同樣可以輕易開發(fā)并發(fā)程序。
本文轉(zhuǎn)載自 dotNET每日精華文章() 微信公眾號
本文作者:朱永光
原文鏈接:http://www.cnblogs.com/redmoon/p/5321229.html#rd
總結(jié)
以上是生活随笔為你收集整理的我为什么喜欢用C#来做并发编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Android Studio进行“简单
- 下一篇: 图形—9patch,shape ,sel