第二章 為什麼需要非同步程式?

2022-06-16 23:57:10 字數 2309 閱讀 4463

眾所周知,非同步程式設計既重要又有用,但是為什麼它如此重要卻要具體問題具體分析,因為這取決於你在編寫什麼樣的程式。有些優點到處都被提及,但真正體現這些優點的場景可能你一輩子也碰不到,如果這和你情況相符,請確保讀完這一章,因為背景知識會幫助你理解整個上下文。

桌面程式有乙個主要的效能需求——需要對使用者操作做出響應。人機互動(hci)調研發現:程式慢一點使用者可以忍,只要使用者點選後介面有響應就行(比如有乙個動畫進度條之類的)。但是如果程式失去響應,使用者就會感到抓狂。失去相應的主要原因就是程式在處理一些耗時操作,比如耗時的計算,或者進行io處理,或者網路請求等。

在c#中你所使用的ui框架基本都只有乙個ui執行緒,比如:

ui執行緒是唯一可以控制特定視窗內容的執行緒,它也是唯一檢查使用者操作並給予響應的執行緒。如果ui執行緒很忙碌或者被阻塞超過幾十毫秒,使用者就會明顯感知到程式的反應延遲。

非同步**意味著ui執行緒可以返回去處理它的主要工作:檢查使用者事件的訊息佇列,然後進行響應。它也可以顯示進度條動畫,在最近版本的windows中,也可以顯示滑鼠懸停動畫,這些都是很重要的視覺化使用者體驗,使用者看到這些後會知道程式一直在對他的行為進行響應。

所有常用的ui框架都只使用乙個ui執行緒,其目的是為了簡化同步工作。如果使用多個ui執行緒,那麼可能會出現這種情況:乙個ui執行緒去讀按鈕的寬度,另乙個ui執行緒在處理空間布局。為了避免這兩個ui執行緒產生衝突,就需要使用鎖等機制進行執行緒間的同步,而這會影響程式的效能。

下面我將舉乙個形象的例子來幫助理解上面的內容,如果你認為自己已經掌握了上面的內容,則可以跳過此章節。

想象有乙個小咖啡館,每天**吐司麵包作為早餐。這個店只有乙個雇員——就是老闆自己。他非常注重顧客對服務的感受,可惜他沒學習過非同步程式設計的技巧。

ui執行緒的模型與此非常類似,在計算機中工作必須通過乙個執行緒來完成自己的任務,在咖啡店的例子中,雇員(也就是老闆自己)只能在咖啡店中做自己的工作。在本例中,咖啡店只有乙個雇員,就好比只有乙個ui執行緒一樣。

第一位顧客要了一片吐司麵包,老闆拿起麵包放到烤麵包機裡,然後他就一直看著烤麵包機工作。這時,顧客問他**有黃油,但是他置若罔聞——因為他已經被「**烤麵包機工作」這件事給阻塞住了。五分鐘後,麵包烤好了,老闆把烤好的麵包拿給顧客,可是顧客卻對他剛才置之不理的行為感到很惱火——這個結果是大家都不想看到的。

現在讓我們看看能不能教教這個老闆如何非同步地進行工作。

首先,他要確保烤麵包機能夠進行非同步工作。當我們編寫非同步**時,我們需要確保耗時操作在工作結束後能夠**。在咖啡館的例子中,烤麵包機必須有個計時器,並且能夠在麵包烤好後很大聲地將麵包彈出來,這樣老闆就會注意到麵包已經好了。

另外,當開始烤麵包後他就不需要在旁邊盯著烤麵包機看了,他應該回去為顧客提供其它服務。同樣地,我們的非同步**必須在開始耗時操作後立即返回,這樣ui執行緒就能夠處理使用者的操作了。這樣做有兩個原因:

咖啡館老闆這時就可以同時給多個顧客提供服務了,唯一的限制就是烤麵包機的個數,以及取麵包、送麵包的時間。

但是目前又有了新的問題:他發現很難記住哪一塊麵包應該給哪一位顧客。事實上,ui執行緒一旦返回,開始處理使用者事件後,它也記不住它在等待哪個操作了。因此,我們需要在啟動新任務時就附件乙個**方法,這個方法的作用就是當耗時操作結束後能夠提醒我們接下來該做什麼。對於咖啡館老闆來說,這個問題很容易解決——在麵包上夾乙個標籤,標籤上寫明顧客的名字就好了。針對我們程式設計的來說,情況要稍複雜些,通常來講我們需要針對任務結束後要做什麼提供完整的指令。

當上面說的都準備就位後,咖啡館老闆就可以非同步工作了,從而他的業務也會迅速擴張。顧客體驗比之前好太多了,因為顧客很少需要等待。

我希望上面的例子能夠幫助你理解為何非同步程式設計對ui程式如此重要。

asp.net web伺服器不像ui程式那樣只有乙個ui執行緒。也就是說,針對web程式來說,使用非同步也會有很多好處。因為在web程式中,執行時間較長的操作,尤其是遠端資料庫查詢等,都是很常見的。 

安裝的iis的版本會決定可以處理web請求的匯流排程數,以及能夠同時處理的請求的數量。如果web請求的大多數時間都花在等待資料庫查詢上,這時為了增加伺服器的吞吐量而增加並行請求的數目,不失為乙個好辦法。

當乙個執行緒被阻塞等待時,它不會占用任何cpu時間。然而,這不等於說它不使用任何伺服器資源。事實上,當執行緒被阻塞時它會產生兩個嚴重的開銷:

這些開銷會增加伺服器的負荷,從而降低系統的吞吐量、增大延遲。

請記住:非同步**的主要特徵就是啟動耗時操作的執行緒,在啟動了耗時操作後就會去做其它事情。在asp.net程式中,執行緒來自於執行緒池,所以當啟動了耗時操作後,執行緒又被放回到執行緒池中,然後它就可以處理其它請求了,因此在這種情況下,處理同樣多的請求卻需要相對較少的執行緒即可。

譯 第二章 什麼是組織

一 組織的理解 1.組織的存在是為了實現目標,組織管理的存在是為了提公升效率 2.公司不是乙個家 組織中我們是以目標,責任,權力來聯結,而不是用情感來聯結的。組織有正式和非正式組織之分,正式組織是指運用權力,責任和目標來鏈結人群的集合 非正式組織是指用情感,興趣和愛好來聯結人群的集合 3.組織必須保...

MySQL第二章總結 Mysql第二章 儲存引擎

1 本章目標 儲存引擎 資料型別 重點 2 儲存引擎 在關係型資料庫中,資料儲存在表中,表由行和列組成。開發中,可能需要各種不同的表,有的表簡單,有的表複雜,有的表讀取快,有的讀取資料慢,有的表更新快等。根據對資料的不同的處理需求,使用不同的儲存引擎,可以將mysql資料庫的效能發揮到最大。查詢my...

領悟(第二章)

當火車緩緩駛進車站的時候,夜幕已經降臨了。終於到了!望著窗外鐵道兩旁的燈火,我的內心不禁再一次的激動起來,一路上對今後在這個大都市的未來生活的想象已經讓我從昨天晚上上車一直興奮到現在了!平常這個時候應該正和朋友們一起在酒吧聊天吧,朋友們,你們現在還在談論我來這裡的目的麼?說實話,這個問題連我自己都說...