c#異步多線程


1.asyncrel = delegate.BeginInvoke實現委托異步調用。
2.異步等待 asyncrel.IsCompleted用於判斷是否執行完畢 or EndInvoke用於等待執行完。
3.異步多線程(資源換時間)使用場景:1.任務比較多,需要提高效率,資源換時間 2.推遲執行,比如發送短信可以異步執行。
4.線程的特點:無序性,啟動順序不確定、執行時間不確定、結束時間不確定。
5.異步多線程均與委托相關。
6.委托.BeginInvoke與Thread.Start() 效果幾乎類似,都能實現異步多線程。區別:Thread是前台線程,程序退出后,計算任務會繼續執行完畢,構造函數對應的委托沒有返回值,沒有回調,也做不到,但是BeginInvoke的可以有返回值,也有回調。
7.線程池:享元模式的實現。也是一種資源換時間的方式,是單例的
8.寫一個5秒炸彈例子,通過ManualResetEvent.
9.Task ,基於線程池。new TaskFactory().StartNew(Action act);Task t=new Task(Action act) t.Start;Task task=Task.Run(Action act);等價
10.Task.WaitAny();Task.WaitAll();卡住當前線程,等待異步線程執行完畢。
11.new TaskFactory().ContinueWhenAny() new TaskFactory().ContinueWhenAll() 實現線程結束后的回調函數。
12.Parallel並行計算。同時開啟多個線程執行但是不是異步,底層還是通過Task實現。
    Parallel.Invoke(),Parallel.For
任務:通過Task封裝一個Parallel
13.異常的處理:多線程的委托是不允許異常的,唯一的處理方式就是通過try catch去隱藏異常並寫日志。因為多線程的異常如果不等待的話是無法抓取的,因為每一個線程有自己的內存空間,自己的執行流。
14.線程取消:通過CancellationTokenSource這個類實現簡單的線程通訊,這個類就像是一個線程間的全局變量。通過設置類實例的屬性進行識別是否要停止,線程不能主動取消,只能通過信號量讓其自己終止自己。cts.Token可以與TaskFactory的參數結合使用,將cts.Token作為TaskFactory.startNew的參數傳遞后,沒有啟動的任務會放棄啟動,框架自動幫我們做了判斷。
new taskFactroy.StartNew(act,name,cts.Token);
15線程安全:多個線程同時訪問同一個共享變量的時候容易觸發。
解決方式:
1.鎖。private static object o=new object();
在操作公共變量的時候
lock(o){
 
},多線程的任務排隊進入,變成單線程。
2.數據隔離。解決線程沖突的根本辦法。
14.async與await成對出現,被async修飾的方法內部都是有task等待的。如果方法只通過async修飾,仍然是同步的效果,只使用await會報錯。
使用效果:
await task(委托);會一直等待多線程執行完畢,執行完畢后,主程序遇到await會直接返回,await后面的代碼會被包裝成一個Action作為一個回調來使用,不在占用主線程。
async修飾的方法為異步方法默認會返回一個Task,即使方法沒有返回值。如果有返回值則返回一個Task<T>
外部調用方式:
private async Task<long> doSomeThing(){}
Task<long> t=doSomeThing();
long rel=t.Result;//會等待異步方法執行完畢
或者使用 t.Wait();
本質上還是異步多線程。
新語法:
        如果是一個async/await的方法,如果方法是沒有返回值的,則可以寫成返回值是Task的形式。
        private async void NoReturn=private async Task NoReturn。推薦后者,如果沒有返回值類型,則返回一個Task,方法其他方法調用時進行wait。
返回值:
        如果沒有返回值,則應該返回一個Task,如果返回一個int類型的值,則應該是Task<t>
        Task<int> t=SumAsync();
        int iRel=t.Result;//訪問result,程序會一直等待計算該結果的線程結束 效果等價於t.Wait();
 
16.線程取消:通過CancellationTokenSource 的實例來完成。該類的實例是所有的線程都可以訪問到的,程序可以通過調用.Cancel()方法將屬性值IsCancellationRequested修改為true,其他線程的代碼可以通過判斷IsCancellationRequested屬性來覺得是否要繼續執行。說白了就是一個全局與所有線程的一個變量。
17.拿到線程的異常:把所有的多線程都放到一個TaskList里面,然后調用WaitAll的時候就可以全部拿到Task.WaitAll(taskList.ToArray());異常的類型:AggregateException。不等待的情況下,多線程的Action(委托)是不允許異常的,方法就是try catch掉,並在catch里寫日志。
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM