Task,異步,多線程簡單總結json
1,如何把一個異步封裝爲Task異步多線程
Task.Factory.FromAsync併發
對老的一些異步模型封裝爲Task框架
TaskCompletionSource異步
更通用,在回調中只要SetResult()一下就表示Task結束了,用它能夠將各類異步回調封裝爲Taskasync
2,一個能夠await的能夠返回Task的Async結尾的異步方法從哪裏開始進入另外一個線程的spa
若是是對BeginXXX EndXXX的APM異步模型封裝的,從進入XXXAsync方法後直到BeginXXX前還在調用方法的線程內,而後無阻塞的等待回調,當等打完後,就至關於在回調中了,此時可能進入了另外一個線程,其餘也是相似的,從底層方法異步的地方開始異步的,而不是一進入方法就到了另外一個線程了,因此進入方法後寫不少CPU密集程序是會阻塞的線程
3,如何馬上扔到另外一個線程code
Task.Run或者Task.Factory.StartNew能夠直接從另外一個線程開始,能夠直接把XXXAsync方法扔進去orm
4,一個約定
純C#框架或者類庫提供的Async結尾的可await方法,裏面必定有無阻塞異步的實現,不然不必搞成異步的,就好比newtonsoft.json的異步序列化方法被標識爲已過期。
5,Task外面如何告訴Task該取消了
CancellationTokenSource
其實和一個Flag差很少,只不過封裝了一些方法以異常類
6,不少狀況下要先學會同步才能併發
7,Task.Run Task.Start Task.Factory.StartNew 等都是使用線程池的線程
8,IO異步底層爲IRP消息,一般是和硬件交互所使用的消息機制,固然那是驅動層的事情,IO異步固然也就是無阻塞的,等IRP消息回來就是回調
9,UI線程
最終會渲染界面的代碼必定要在UI線程執行,可使用好比winform的control.Invoke ,wpf的Dispatcher , 還有利用SynchronizationContext
10,異常處理
var checkT1 = Task.Run(async () => { throw new Exception("1"); throw new Exception("2"); }); try { await checkT1; } catch (AggregateException ex) { ex.Flatten(); foreach (var item in ex.InnerExceptions) { MessageBox.Show("show1:" + item.Message); } } catch (Exception ex2) { MessageBox.Show("show2:" + ex2.Message); }
var checkT1 = Task.Run(() => { throw new Exception("1"); throw new Exception("2"); }); try { await checkT1; } catch (AggregateException ex) { ex.Flatten(); foreach (var item in ex.InnerExceptions) { MessageBox.Show("show1:" + item.Message); } } catch (Exception ex2) { MessageBox.Show("show2:" + ex2.Message); }
以上兩種,輸出 show2:1,也就是當即拋出原來的異常,在等待時可捕獲
var checkT1 = Task.Run(async () => { throw new Exception("1"); throw new Exception("2"); }); try { checkT1.Wait(); } catch (AggregateException ex) { ex.Flatten(); foreach (var item in ex.InnerExceptions) { MessageBox.Show("show1:" + item.Message); } } catch (Exception ex2) { MessageBox.Show("show2:" + ex2.Message); } var checkT1 = Task.Run(() => { throw new Exception("1"); throw new Exception("2"); }); try { checkT1.Wait(); } catch (AggregateException ex) { ex.Flatten(); foreach (var item in ex.InnerExceptions) { MessageBox.Show("show1:" + item.Message); } } catch (Exception ex2) { MessageBox.Show("show2:" + ex2.Message); }
以上兩種 Show1:1 ,也就是進入AggregateException異常處理
var checkT1 = Task.Factory.StartNew(async () => { throw new Exception("1"); throw new Exception("2"); });
會吞掉異常
此時須要用GetAwaiter
12:各類同步類,併發類
待補充
一旦開始併發了,還有不少不少的坑