C# 非同步程式設計
使用非同步程式設計,方法呼叫時在後臺執行,並且不會阻塞呼叫執行緒。
非同步程式設計模型Async Patterns Model(APM)
非同步模式定義了BeginXXX和EndXXX方法。BeginXXX方法接受其同步方法的所有輸入引數,EndXXX方法使用同步方法的所有輸出引數,並按照同步方法的返回型別來返回結果。
//非同步模式定義了BeginXXX和EndXXX方法
WebRequest request = WebRequest.Create("http://www.baidu.com");
var result = request.BeginGetResponse((obj) => {
}, null);
var resp = request.EndGetResponse(result);
基於事件的非同步模式Event-based Async Pattern(EAP)
基於事件的非同步模式定義了一個帶有“Async”字尾的方法。例如,對於同步方法DownloadString,WebClient提供了非同步方法DownloadStringAsync。並且你需要編寫DownloadStringCompleted事件,這個事件會在非同步方法完成後呼叫。
基於事件的非同步方法優勢在於易於使用。但是,在自定義類中這個模式就沒有這麼簡單了。
//基於事件的非同步模式定義了一個帶有“Async”字尾的方法
var client = new WebClient();
client.Encoding = Encoding.UTF8;
client.DownloadStringCompleted += (sender1, e1) =>
{
var resp = e1.Result;
};
client.DownloadStringAsync(new Uri("http://www.baidu.com"));
基於任務的非同步模式Task-based Async Pattern(TAP)
該模式定義一個帶有“Async”字尾的方法,並返回一個Task型別。例如WebClient提供的基於任務的非同步方法DownloadStringTaskAsync,該方法返回一個Task<string>,可以用string類接收它,並使用await關鍵字,await關鍵字會解除執行緒(UI執行緒)的阻塞,完成其他任務。
//基於任務的非同步模式
var client = new WebClient();
client.Encoding = Encoding.UTF8;
string resp = await client.DownloadStringTaskAsync("http://www.baidu.com");
async和await關鍵字只是編譯器的功能。編譯器會用Task類建立程式碼。如果不使用者兩個關鍵字,也可以用C# 4.0和Task類的方法來實現同樣的功能,只是沒有那麼方便。
async修飾符只能用於返回.NET型別的Task或void方法,以及Window執行庫的IAsyncOperation。
Task類的ContinueWith方法定義了任務完成後就呼叫的程式碼。指派給ContinueWith方法的委託接收已完成的任務作為引數傳入,使用Result屬性可以訪問任務返回的結果。
public string Greeting(string name)
{
//同步任務
Task.Delay(2000).Wait();//等同於Thread.Sleep()
return "hello " + name;
}
public Task<string> GreetingAsync(string name)
{
//非同步任務
return Task.Run<string>(() => {
return Greeting(name);
});
}
//延續任務
Task<string> task = GreetingAsync("Xie");
task.ContinueWith(t => {
var msg = t.Result + " !";
MessageBox.Show(msg);
});
Task類定義了WhenAll和WhenAny組合器。從WhenAll方法返回的Task,是在所有傳入方法的任務都完成了才會返回Task。從WhenAny方法返回的Task,是在其中一個傳入方法完成了就會返回Task。
Task<string> task = GreetingAsync("Wang");//耗時2秒
Task<string> task2 = GreetingAsync2("Bai");//耗時6秒
//其中一個執行緒執行完畢就會繼續執行
//var task3 = await Task.WhenAny(task, task2);
//MessageBox.Show(task3.Result);
//當所有執行緒執行完才會繼續執行
var task3 = await Task.WhenAll(task, task2);
MessageBox.Show(task3[0] + "," + task3[1]);
想了解更多關於C# 6與.NET Core的知識請參考:《C#高階程式設計》
相關文章
- C#非同步程式設計C#非同步程式設計
- C# - 非同步程式設計 - BackgroundWorker 類C#非同步程式設計
- [譯] 非同步程式設計:阻塞與非阻塞非同步程式設計
- C#非同步程式設計:原理與實踐C#非同步程式設計
- C# 非同步程式設計Task(三) async、awaitC#非同步程式設計AI
- C#非同步程式設計由淺入深(一)C#非同步程式設計
- 第二章:C#非同步程式設計簡介C#非同步程式設計
- C#非同步程式設計是怎麼回事(番外)C#非同步程式設計
- 【進階之路】併發程式設計(三)-非阻塞同步機制程式設計
- 一文說通C#中的非同步程式設計C#非同步程式設計
- 一文徹底搞定(阻塞/非阻塞/同步/非同步)網路IO、併發程式設計模型、非同步程式設計模型的愛恨情仇非同步程式設計模型
- c#程式設計C#程式設計
- 非同步程式設計非同步程式設計
- C#非同步程式設計由淺入深(三)細說AwaiterC#非同步程式設計AI
- Java 網路程式設計 —— 非阻塞式程式設計Java程式設計
- 簡單理解非同步程式設計(python)和非同步程式設計(nodejs)非同步程式設計PythonNodeJS
- 非同步程式設計:基於事件的非同步程式設計模式(EAP)非同步程式設計事件設計模式
- java非同步程式設計Java非同步程式設計
- asyncio 非同步程式設計非同步程式設計
- 非同步程式設計 CompletableFuture非同步程式設計
- Dart 非同步程式設計Dart非同步程式設計
- Javascript 非同步程式設計JavaScript非同步程式設計
- php非同步程式設計PHP非同步程式設計
- 非同步程式設計---Promise非同步程式設計Promise
- js 非同步程式設計JS非同步程式設計
- C#多執行緒程式設計-基元執行緒同步構造C#執行緒程式設計
- 一文說通C#中的非同步程式設計補遺C#非同步程式設計
- C#非同步程式設計由淺入深(二)Async/Await的作用.C#非同步程式設計AI
- 《JAVA併發程式設計實戰》原子變數和非阻塞同步機制Java程式設計變數
- 阻塞式程式設計和非阻塞式程式設計區別程式設計
- 美女程式設計師觀點:程式設計師最重要的非程式設計技巧程式設計師
- C# 管道式程式設計C#程式設計
- C# 併發程式設計C#程式設計
- C#進階——從應用上理解非同步程式設計的作用(async / await)C#非同步程式設計AI
- NIO非阻塞程式設計小案例程式設計
- Flutter 非同步程式設計指南Flutter非同步程式設計
- 非同步程式設計筆記非同步程式設計筆記
- EF Core非同步程式設計非同步程式設計