C#多執行緒之Await&Async學習筆記
C# 5.0語法糖,依託Task存在,本身不會產生執行緒,達到了通過非同步方法實現同步效果的目的(解決非同步多執行緒執行順序難控制的問題)
1.定義
async可以隨便新增,可以不用新增await
await只能出在Task前面,但是方法必須宣告async,不能單獨出現
await/async之後,原本沒有返回值,可以返回Task
原本返回T型別的,返回Task<T>
儘量不要返回void,因為不能再await了
2.執行順序
namespace AwaitAsyncTest { class Program {static void Main(string[] args) { AwaitAsyncClassNew awaitTest = new AwaitAsyncClassNew(); awaitTest.Show(); Console.ReadKey(); } } class AwaitAsyncClassNew { public void Show() { Console.WriteLine($"This is MainThread Start{Thread.CurrentThread.ManagedThreadId}"); this.NoReturnTask(); Console.WriteLine($"This is MainThread End {Thread.CurrentThread.ManagedThreadId}"); } public async Task NoReturnTask() { Console.WriteLine($"This is NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}"); Task task= Task.Run(() => { Console.WriteLine($"NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); Console.WriteLine($"NoReturnTask End{Thread.CurrentThread.ManagedThreadId}"); });//呼叫執行緒發起,啟動新執行緒執行內部動作 await task;//呼叫執行緒回去忙自己的事 Console.WriteLine($"This is NoReturnTask End{Thread.CurrentThread.ManagedThreadId}");//由子執行緒完成(如果沒有await,應該由呼叫執行緒執行) } }
執行結果:
This is MainThread Start1
This is NoReturnTask Start1
This is MainThread End 1
NoReturnTask Start3
NoReturnTask End3
This is NoReturnTask End3 --本來屬於主執行緒的卻被子執行緒執行了
相當於await的後續程式碼包裝成了一個回撥,執行次此回撥的執行緒有多種可能性
將await開始的程式碼換成
public async Task NoReturnTask() { Console.WriteLine($"This is NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}"); Task task = Task.Run(() => { Console.WriteLine($"NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); Console.WriteLine($"NoReturnTask End{Thread.CurrentThread.ManagedThreadId}"); }); //await task; //Console.WriteLine($"This is NoReturnTask End{Thread.CurrentThread.ManagedThreadId}"); task.ContinueWith(t => Console.WriteLine($"This is NoReturnTask End{Thread.CurrentThread.ManagedThreadId}")); }
結果為
This is MainThread Start1
This is NoReturnTask Start1
This is MainThread End 1
NoReturnTask Start3
NoReturnTask End3
This is NoReturnTask End4
如果再更多層的await,執行順序依次向後(更像是順序執行了),相當於用同步的形式去寫非同步
public async Task NoReturnTask() { Console.WriteLine($"This is NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}"); Task task = Task.Run(() => { Console.WriteLine($"NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); Console.WriteLine($"NoReturnTask End{Thread.CurrentThread.ManagedThreadId}"); }); await task; Console.WriteLine($"This is NoReturnTask End{Thread.CurrentThread.ManagedThreadId}"); //task.ContinueWith(t => // Console.WriteLine($"This is NoReturnTask End{Thread.CurrentThread.ManagedThreadId}")); await Task.Run(() => { Console.WriteLine($"NoReturnTask2 Start{Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); Console.WriteLine($"NoReturnTask2 End{Thread.CurrentThread.ManagedThreadId}"); }); Console.WriteLine($"This is NoReturnTask2 End{Thread.CurrentThread.ManagedThreadId}"); }
結果為
This is MainThread Start1
This is NoReturnTask Start1
NoReturnTask Start3
This is MainThread End 1 --主執行緒結束
NoReturnTask End3
This is NoReturnTask End3 --執行完task1
NoReturnTask2 Start4 ---執行Task2
NoReturnTask2 End4
This is NoReturnTask2 End4
3.執行緒ID問題
4.返回值問題