斜體字: 表示新定義的術語、url、郵件位址、檔名、副檔名。
下面的圖示表示:小貼士|、建議或者注釋。
首先,讓我們從較高層次介紹一下c# 5.0中的async功能,看看它對你意味著什麼。
什麼樣的**是非同步的呢?如果程式開始執行耗時操作後,不會等待耗時操作結束才往下執行,這樣的**就是非同步的。如果程式一直等待耗時操作結束後,才會繼續往下執行,這樣的**就是阻塞**(blocking code)。
常見的耗時操作包括下列場景:
對於我們通常使用的程式語言來說,程式都在作業系統執行緒上執行。如果當執行耗時操作時,這個執行緒繼續去做其它事情,這樣的**就是非同步的;如果這個執行緒什麼事也不做(被阻塞了),這樣的**就是阻塞的。所以說,區分非同步和阻塞**的重點的就在於執行**的執行緒。
當然,解決等待耗時操作問題的第三種策略是:輪詢(polling)——你可以反覆詢問任務是否已經結束。
但通常來說不推薦這種方法,因為它只適用於操作時長不太久的情況。
在你之前的工作中,你也許已經使用過非同步程式設計了。
這些看起來也許很明顯,但是假象一下如果你要寫乙個控制台程式,你會使用console.readline()方法獲取使用者輸入,也許對於web你也會採用類似的阻塞式設計。雖然這種設計看起來很糟糕,但是這完全可能發生。
書寫非同步**的難點通常在於:你需要知道耗時操作具體在什麼時候結束了,然後**就可以繼續做其它的事情了。如果是阻塞式**,這一切做起來都很容易——直接在耗時操作下寫**就行了。然而在非同步的世界裡,這麼做可不行,因為耗時操作下面的**極有可能會在耗時操作完成之前就已經執行了。
為了解決這個問題,我們發明了一些模式以達到在後台操作結束後能夠執行指定**的目的:
如果接下來要執行的操作需要在特定的執行緒上執行(例如:winfrom或wpf的ui執行緒),你還需要在特定執行緒上將後續操作排隊。
這些處理方式多多少少都有些混亂。
非同步**會釋放啟動非同步邏輯的執行緒,這樣做有很多好處:執行緒會占用機器上的資源,而程式使用的資源肯定是越少越好。通常來說,乙個執行緒會執行一些特定的任務,比如ui執行緒,如果不及時釋放ui執行緒,你的程式就會失去響應,相關原因我會在下一章詳細講解。
關於使用非同步程式設計,令我為之興奮的乙個最大原因就是它能充分發揮平行計算的優勢。async使得你能以更合理的方式組織你的程式,而不會是你的**變得複雜和難以維護。第10章會對此進行詳細闡釋。
在c#語言的5.0版本中,微軟的編譯器團隊增加了乙個強大的新功能,體現在下面兩個關鍵字上
當然,這也依賴於.net framework 4.5上的新功能和變化,才使得它如此強大和實用。
async是c#編譯器的功能,而不是依賴庫實現的。它會對你的源**進行轉換,與之前c#版本中引入的labmda表示式和迭代器非常類似的。
async這一功能使得非同步程式設計變得容易多了,因為在它出現之前,c#之前版本中需要使用複雜的模式才能實現非同步程式設計,而async的出現使得這些複雜模式不再是必須的。有了async,我們可以用更加合理的方式來書寫整個程式。
縱貫本書,我會使用術語「非同步」(asynchronous)來代指程式設計方式,「async」則指c#引入的新功能。
在c#中一直都可以實現非同步程式設計,但是對於程式設計師來說,這會引入許多手動的工作。
private void dumpwebpage(string uri)下面是使用了async的非同步方式:
private async void dumpwebpageasync(string uri)這兩段**看起來極其相似,但是實際上卻有著很大的不同。
任何使用await關鍵字的方法都需要被標註為async。為了遵守命名慣例,方法名也會以async結尾(dumpwebpageasync)。比較有意思的是await關鍵字,當編譯器看到它之後,方法會被「切碎」,但具體背後做了什麼是很難用三言兩語就講清楚的,所以我暫時使用下面的方式進行思考,雖然與事實不完全相符,但是卻能夠幫助我們進行理解
await關鍵字後的**都被放到乙個單獨的方法中(稱為secondhalf)
我們使用了downloadstring的乙個新版本downloadstringasync,它的功能和downloadstring一樣,但是卻是非同步的
當downloadstringasync方法結束自身的任務後,它會呼叫前面說的secondhalf方法。我們使用了一些神奇的方法達到了這個目的,但是具體怎麼做的我在後面會講。
private void dumpwebpageasync(string uri)async功能被設計得盡可能使寫出的**看起來和阻塞式非常相似,這樣我們可以把耗時操作或者遠端操作當作發生在本地或者可以快速執行完一樣去對待,通過非同步呼叫它們,從而保持了非同步的效能優勢。private void secondhalf(string awaitedresult)
然而,這樣設計的初衷不是要你忘記了下面的事實:這些操作其實都是在後台執行的操作,並且用到了**的方式。當你使用async時需要對下面的情況格外小心:
如果不理解async背後到底發生了什麼,你的程式可能會不可思議地失敗,並且你可能看不懂程式報出的錯誤資訊,從而無法修復問題。
深度學習 第一章 引言
本文為閱讀總結個人認為書裡概念性的 對本人有幫助的內容,僅供參考。我們期望通過智慧型軟體自動地處理常規勞動 理解語音或影象 幫助醫學診斷 支援基礎科學研究。人工智慧的真正挑戰在於解決那些對人來說很容易執行 但很難形式化描述的任務。對於這些問題,我們人類往往可以憑藉直覺輕易地解決。層次化的概念讓計算機...
筆記 吳恩達第一章引言
一 引言 introduction 1.1 歡迎 1.2 機器學習是什麼?1.3 監督學習 1.4 無監督學習 暫空特徵 樣本點有標記資訊,如房價 問題 良性腫瘤與惡性腫瘤分類問題等 監督學習的分類 回歸 regression 針對連續型問題,如房價 問題 predict real valued o...
《設計模式》讀書筆記 第一章 引言
模式名稱 問題 描述應該在何時使用模式 解決方案 描述了設計的組成成分,他們之間的相互關係及各自的職責和協作方式 效果 描述模式應用的效果及使用模式應權衡的問題 建立型 與物件的建立有關 處理類和物件的組合 對類和物件怎樣互動和怎樣分配職責進行描述 類模式 處理類和子類之間的關係,這些關係通過繼承建...