如果需要 i/o 繫結(例如從網路請求資料或訪問資料庫),則需要利用非同步程式設計。 還可以使用 cpu 繫結**(例如執行成本高昂的計算),對編寫非同步**而言,這是乙個不錯的方案。
非同步程式設計的核心是task
和task
物件,這兩個物件對非同步操作建模。 它們受關鍵字async
和await
的支援。 在大多數情況下模型十分簡單:
對於 i/o 繫結**,當你await
乙個操作,它將返回async
方法中的乙個task
或task
。
對於 cpu 繫結**,當你await
乙個操作,它將在後台執行緒通過task.run
方法啟動。
編寫**前應考慮的兩個問題:
1.你的**是否會「等待」某些內容,例如資料庫中的資料?
如果答案為「是」,則你的工作是 i/o 繫結。
2.你的**是否要執行開銷巨大的計算?
如果答案為「是」,則你的工作是 cpu 繫結。
如果你的工作為 i/o 繫結,請使用async
和await
(而不使用task.run
)。 不應使用任務並行庫。 相關原因在深入了解非同步的文章中說明。
如果你的工作為 cpu 繫結,並且你重視響應能力,請使用async
和await
,並在另乙個執行緒上使用task.run
生成工作。 如果該工作同時適用於併發和並行,則應考慮使用任務並行庫。
假設你正在編寫乙個移動遊戲,在該遊戲中,按下某個按鈕將會對螢幕中的許多敵人造成傷害。 執行傷害計算的開銷可能極大,而且在 ui 執行緒中執行計算有可能使遊戲在計算執行過程中暫停!
此問題的最佳解決方法是啟動乙個後台執行緒,它使用task.run
執行工作,並await
其結果。 這可確保在執行工作時 ui 能流暢執行。
privatedamageresult calculatedamagedone()
calculatebutton.clicked += async (o, e) =>;
它無需手動管理後台執行緒,而是通過非阻止性的方式來實現。
此示例演示如何為一組user
捕捉userid
資料。
publicasync taskgetuserasync(int
userid)
, retrieves a user object corresponding
//to the entry in the database with as its id.
}public
static
async task> getusersasync(ienumerableuserids)
return
await
task.whenall(getusertasks);
}
以下是使用 linq 進行更簡潔編寫的另一種方法:
publicasync taskgetuserasync(int
userid)
, retrieves a user object corresponding
//to the entry in the database with as its id.
}public
static
async taskgetusersasync(ienumerableuserids)
儘管它的**較少,但在混合 linq 和非同步**時需要謹慎操作。 因為 linq 使用延遲的執行,因此非同步呼叫將不會像在foreach()
迴圈中那樣立刻發生,除非強制所生成的序列通過對.tolist()
或.toarray()
的呼叫迴圈訪問。
linq 中的 lambda 表示式使用延遲執行,這意味著**可能在你並不希望結束的時候停止執行。 如果編寫不正確,將阻塞任務引入其中時可能很容易導致死鎖。 此外,此類非同步**巢狀可能會對推斷**的執行帶來更多困難。 async 和 linq 的功能都十分強大,但在結合使用兩者時應盡可能小心。
C 非同步程式設計
同步方法和非同步方法的區別 同步方法呼叫在程式繼續執行之前需要等待同步方法執行完畢返回結果 非同步方法則在被呼叫之後立即返回以便程式在被呼叫方法完成其任務的同時執行其它操作 非同步程式設計概覽 net framework 允許您非同步呼叫任何方法。定義與您需要呼叫的方法具有相同簽名的委託 公共語言執...
C 非同步程式設計
一 基礎知識 1 非同步程式設計 2 非同步方法 乙個程式呼叫某個方法,在處理完成前就返回該方法。同步和非同步主要用於修飾方法。當乙個方法被呼叫時,呼叫者需要等待該方法執行完畢並返回才能繼續執行,我們稱這個方法是同步方法 當乙個方法被呼叫時立即返回,並獲取乙個執行緒執行該方法內部的業務,呼叫者不用等...
C 非同步程式設計
定義要求 方法簽名包含 async 修飾符。按照約定,非同步方法的名稱以 async 字尾結尾。返回型別為下列型別之一 1.如果你的方法有運算元為 tresult 型別的返回語句,則為 task。2.如果你的方法沒有返回語句或具有沒有運算元的返回語句,則為 task。3.void 如果要編寫非同步事...