Task C# 多線程和異步模型 TPL模型

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:各類同步類,併發類

待補充

 

一旦開始併發了,還有不少不少的坑

相關文章
相關標籤/搜索