1. 引入web
同步,任務以固定的順序執行。異步,任務不須要按照固定順序執行。從.net4.5開始,異步主要經過Task實現。異步編程的核心是Task和Task<T>對象,用來模擬異步操做,並經過async和await關鍵字修飾。其中異步模型的操做,通常分爲如下2種:數據庫
(1)對於I/O綁定的代碼,await將在異步方法中返回一個Task或Task<T>;編程
(2)對於綁定CPU類的程序,await將在帶有Task.Run()方法的後臺線程上啓動操做;緩存
2. 異步編程的三種模式異步
這三種模式的實現,以"從指定的偏移量開始將指定數量的數據讀入提供的緩存區"爲例進行實現。async
public class MyClass { public int Read(byte[] buffer, int offset, int count); }
該方法的TAP模式實現以下:異步編程
public class MyClass { public Task<int> ReadAsync(byte[] buffer, int offset, int count); }
EAP對應方法將公開一下類型和成員:測試
public class MyClass { public void ReadAsync(byte [] buffer, int offset, int count); public event ReadCompletedEventHandler ReadCompleted; }
APM模式下實現以下:spa
public class MyClass { public IAsyncResult BeginRead(byte [] buffer,int offset, int count,AsyncCallback callback, object state); public int EndRead(IAsyncResult asyncResult); }
3. 異步操做的實現.net
3.1 I/O綁定實例
場景描述: 點擊按鈕從web服務下載數據,但不能鎖定UI線程。
private readonly HttpClient _httpClient=new HttpClient(); downloadButton.Click +=async (o,e)=> { //在web服務請求發生時間向UI提供控制 //UI線程自由地執行其餘工做 var stringData = await _httpClient.GetStringAsync(URL); DoSomethingWithData(stringData); }
3.2 CPU綁定實例:執行遊戲計算
場景描述:寫一個手機端遊戲,點擊按鈕對屏幕上許多敵人形成傷害,但執行損害計算的代價多是昂貴的,而且在UI線程上執行計算時可能致使界面暫停。
解決該問題的最佳辦法是開啓一個用Task.Run工做的後臺線程,用await等待返回結果。
private DamageResult CalculateDamageDone() { // Code omitted: // // Does an expensive calculation and returns // the result of that calculation. } calculateButton.Clicked += async (o, e) => { // This line will yield control to the UI while CalculateDamageDone() // performs its work. The UI thread is free to perform other work. var damageResult = await Task.Run(() => CalculateDamageDone()); DisplayDamage(damageResult); };
3.3 關鍵點
3.4 如何分辨是I/O綁定仍是CPU綁定?
(1)若是代碼須要「等待」,例如來自數據庫的數據,則爲I/O綁定;
(2)若是代碼執行須要消耗大代價的計算,則爲CPU綁定。
4. 總結