成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C#異步編程及其同步機制

開發 后端
前幾天公司內部有人搞了一個關于多線程及其同步問題的講座,內容很豐富,覆蓋面很廣,讓人聽了大呼過癮。他采取了橫向鋪陳的方法講的,羅列了C#下異步編程方法和模式及各種同步機制,這種講述方式對于熟悉這塊的人來說總結一下,幫助很大,但對于新手有可能就云里霧里了。雖然我研究不深,但縱向講一下這一塊內容,對新手入門有可能會有所幫助,也算是自己對這塊內容的一種總結。只討論技術,不涉及細節和Demo。

 本篇文章涵蓋一下幾部分內容:

    1. 什么是異步編程,為什么會需要異步編程

    2. .NET下的異步編程及其發展

    3. .NET線程同步機制及線程間數據封送

    4. 異步模式

    5. 線程安全及異常處理

    6. 線程取消

什么是異步編程,為什么會需要異步編程

           這個世界上資源是受限的。但資源限制和懶惰一樣促進了工業和科技的發展。在計算機方面舉個例子,計算機非得是二進制嗎?對計算機來說二進制***嗎?不是,這是由于當時工業水平限制,把電壓分成兩份表示0和1比分成三份更加方便且可靠;虛擬內存管理,Cache等技術都是由當時硬件條件所限逼出來的技術,同樣異步編程和分布式編程也是。生活中的好多事物都不是線性的,拿學生時代的一個常見的例子說一下,明天開學,海量作業一點沒寫,于是找個同學作業抄一下,但在短時間內一個人很難抄得完,于是我花錢請了幾個同學一起抄,把一份工作分給幾個人去做,這就是異步了。但除去筆跡不同這么做沒有一個人抄安全,有可能哥幾個把一份內容重復抄了好幾遍(線程安全),這期間萬一筆,紙,橡皮沒準備充分還得有一個資源爭用,死鎖的問題(同步的問題),哥幾個抄得時候還會相互報一下各自進度(線程間數據封送),所以說這么干是有風險的我們就得有個機制避免這種風險的發生,異步編程和這個類似。

          那在編程中異步會用在什么地方呢?一個簡單情形,圖形界面程序,后臺如果要連接數據庫查詢或寫入海量數據或者進行I/O操作,界面會“假死”。之所以發生這種情況是這些處理都在UI線程中,這些操作占用UI線程時,任何拖動UI,點擊按鈕等操作都得不到及時響應。解決的方法是將這些需要長時間的操作放入一個新的線程異步操作,把UI線程解放出來。其它的應用比如海量數據計算,服務器響應客戶端請求等等。

.NET下的異步編程及其發展

         首先說明一點,線程可以分為前臺線程和后臺線程。前臺線程和吸血鬼差不多很恐怖,要想干死進程,就必須把所有的前臺進程都干掉,UI線程就是前臺線程。而后臺線程就是二房生的兒子了,進程消亡后緊跟著死掉了,很明顯的后臺線程就是Word的拼寫檢查,或者outlook負責跟服務器同步更新郵件的線程。

        任何平臺和編程語言都會有多線程的實現機制和方法。對于C#來講Thread類就是創建線程,管理線程的一種最初始的手段。但是創建和銷毀一個線程是很耗費資源的,而且創建的線程越多,線程間切換就越頻繁(計算機CPU個數受限),線程切換也要耗費資源和時間,再加上線程管理是一件很費心的事,所以微軟就引入了線程池的概念。線程池是一個先進先出FIFO的隊列,程序員只需要把操作或者任務丟給線程池,讓.NET framework替程序員管理線程,線程復用等,極大的簡化了開發。這里就有一個控制線程池內線程數量的問題。線程池內的線程肯定得根據需要動態變化,但適應這種需要的算法是什么呢?

          一個簡單的算法:往線程池中增加一些線程,觀察線程池的吞吐量,如果增加后吞吐量增加,說明線程不夠,需要增加線程。但這存在一個問題,對于一個很大的任務需要長時間占用線程,增加線程并不能增加吞吐量,此時如果增加線程會加重負擔。所以在CLR v4時引入了本地隊列(Local  Queue)的概念,如果一個線程內創建了另一個線程,新創建的線程不再丟給全局隊列,而是給本地隊列排隊等候調用。這就又有個問題,如果一個隊列內任務執行完了,而另一個隊列還有好多怎么辦?那就讓執行完任務的本地隊列從該隊列上“偷“一個線程執行。這樣達到負載均衡。當然線程池的算法會隨著CLR版本升級而不斷演進,更加智能的管理線程。對普通開發者而言可以不用考慮這些細節,無縫的體驗線程池帶來的便利和效率就行了。                   

       線程池如此方便,我們怎么使用線程池呢?可以通過以下幾種方式:

通過類方法ThreadPool.QueueUserWorkItem直接調用。

通過.net Framework 4.0 引入的TPL(Task Parallel Library)任務并行庫。

         TPL中最主要的兩個類是Task和Parallel。而新版C++標準中也引入了類似的概念parallel_for, parallel_foreach, parallel_invoke等。

         詳細信息見以下鏈接。

通過異步委托(BeginInvoke/EndInvoke)調用。

通過BackgroundWorker, BackgroundWorker是WinForm, WPF下的一個控件,主要用于提供UI控件下的協作式取消,進度報告等。

        這里我還要講一下PFX(Parallel FrameWork)。PFX從概念上可以分為數據并行和任務并行。

上層的由兩個結構化數據并行APIs組成:PLINQ和Parallel類。而底層的任務并行包含了Task 類和一系列的附屬結構用于幫助并行編程。注意PFX是建立在線程池之上的,是更好使用線程池的一種途徑,有說法說是用TPL比直接使用線程池效率更高。關于PLINQ,Task,Parallel類及上圖所列結構的使用請參考一下鏈接。

.NET線程同步機制及線程間數據封送

        首先.Net的同步機制是干什么的?概況來講是為了安全。同步機制的存在是因為異步操作是不安全的,會帶來一系列的問題,這些問題在***章節中已經討論過了。而線程間數據封送和COM與.Net framework數據封送一樣,是為了線程間數據和狀態的傳遞。

那么.net的同步機制有哪些呢?概括一下:

  1.   簡單的鎖定方法:Thead類的Sleep, Join等以及Task的Wait方法。

  2.   基于對象的鎖定:

                 lock(Monitor.Enter/Monitor.Exit):首先強調一下它不可以跨進程間線程同步。一般跨進間線程同步都有一個特征,就是同步對象都有名字。

                 Mutex和Semophore(slim):這兩個都可以跨進程同步,兩者的區別在于:Mutex只能有一等待資源,而Semophore可以有多個。拿廁所舉例,Mutex相當于廁所中只有一個蹲位,只能一個上了才能上另一個,而Semophore可以有多個蹲位,可以讓多個線程同時阻塞一個線程的執行。就是n個哥們一起蹲著,又來一哥們,然后這n個哥們就占著那啥不那啥。

                 Reade/Writer 鎖。

     3.基于信號

                事件等待句柄AutoResetEvent, ManualResetEvent(Slim):注意這兩個也是允許跨進程的,兩者用法差不多,使一個線程釋放一個信號從而使得其他線程能夠執行。

                CountdownEvent(4.0被引入):這個和上邊用法正好相反,它使得一個線程等待收到其他線程的信號后再執行。

                Barrier

                Wait and pulse

     4. 非阻塞的同步結構

                Thread.MemoryBarrier

                Thread.VolatileRead/Write

                Interlocaked   

  關于以上同步機制具體應用和Demo代碼請參考以下鏈接。

  而關于線程間數據封送,一個很好的例子就是點擊button后開始在新線程中執行某個操作,但執行過程需要在一個label上顯示出來,這時候就需要把新線程內表示執行狀態的數據對象封送回UI線程。這部分內容可以參考我以前寫的一篇帖子:http://www.cnblogs.com/salomon/archive/2012/06/28/2567339.html。                        

異步模式

    什么需要異步模式?所謂模式,其實是一種方法,就跟上篇博客里所講的,是從工程實踐中總結出來的解決相似或特定問題的一種慣用手段。常見的異步模式包括:

      APM模式: BeginXXX/EndXXX, IAsyncResult

      EAP模式(基于事件的異步模式)

           Windows Form

           MethodNameAsync

           Event

     TAP(基于任務的異步模式)

           MethodNameAsync

           Task/Task<Result>

     這部分內容以下鏈接講得很好了,感興趣可以看一下。更詳盡的介紹去MSDN或者官方網站上去找相似的文檔。

線程安全及異常處理

   新線程中拋出的異常會不會自動封送到主線程中?如何處理新線程中拋出的異常?什么是線程安全?怎樣做到線程安全?

線程取消

   正在執行的線程怎么能不能取消,怎么取消合適?暴力取消?協作式取消?

C#5.0新的異步模式Async和await關鍵字

   請參考我以前的博客:http://www.cnblogs.com/salomon/archive/2012/06/27/2565862.html

原文鏈接:http://www.cnblogs.com/salomon/archive/2012/07/26/2610548.html

【編輯推薦】

  1. C#、LINQ與ADO.NET主從表比對操作
  2. C#幾個經常犯錯誤匯總
  3. C#開發高性能Log Help類設計開發
  4. C#使用委托調用實現用戶端等待閃屏
  5. 淺談C#結構

責任編輯:彭凡 來源: 博客園
相關推薦

2012-07-09 09:25:13

ibmdw

2025-03-31 00:01:12

2015-09-16 15:11:58

C#異步編程

2021-10-12 17:47:22

C# TAP異步

2017-12-15 10:20:56

MySQLInnoDB同步機制

2019-05-27 14:40:43

Java同步機制多線程編程

2011-11-23 10:09:19

Java線程機制

2009-08-20 17:30:56

C#異步編程模式

2024-07-05 08:32:36

2021-03-23 07:56:54

JS基礎同步異步編程EventLoop底層

2024-06-28 08:45:58

2009-08-21 10:28:21

C#異步方法C#同步方法

2009-08-12 13:37:01

Java synchr

2010-03-15 16:31:34

Java多線程

2016-12-14 15:05:08

C#異步編程

2009-08-20 17:47:54

C#異步編程模式

2025-04-30 01:50:00

C#異步編程

2024-10-15 08:29:09

C#軟件開發

2009-10-20 16:48:30

C#委托

2019-08-22 14:30:21

技術Redis設計
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲国产精品一区二区三区 | 91精品久久久久久久久中文字幕 | 久久精品国产一区 | 伦理二区| 国产女人叫床高潮大片免费 | 99久久亚洲| 一区二区av| 九九精品在线 | 一区二区三区视频在线观看 | 久久综合一区 | 国产精品入口久久 | 免费一看一级毛片 | 久久国产精品一区二区 | 精品日本久久久久久久久久 | 精品日韩一区 | 欧美日韩亚洲系列 | 一区二区高清 | 成人免费久久 | 夜夜夜夜夜夜曰天天天 | 国产亚洲欧美在线 | 中文字幕视频一区二区 | 国产久视频 | 狠狠躁躁夜夜躁波多野结依 | aaaa日韩| 国外成人在线视频网站 | 黄色精品 | 亚洲精品一级 | 在线日韩中文字幕 | 日韩在线小视频 | 毛片免费看 | 亚洲精品性视频 | 国产精品 亚洲一区 | 丁香婷婷在线视频 | 91人人看 | 亚洲精品一区二区三区四区高清 | 日日骚网 | 男女免费观看在线爽爽爽视频 | 久久国产精品久久国产精品 | 国产精品毛片无码 | 欧美国产一区二区 | 欧美亚洲国产日韩 |