.NET多執行緒(五)非同步操作
5、非同步操作
5.1 非同步操作基礎
非同步操作發展歷史,APM模式,EAP模式,TPL模式
.NET 1.0
System.Threading.Thread
適用耗時操作、特殊操作、低優先順序操作,預設前臺
System.Threading.ThreadPool
適合短時操作,執行緒池執行緒預設後臺
# APM 非同步操作模式
.NET 2.0
Thread 構造支援 ParameterizedThreadStart 傳引數
匿名方法 delegate,閉包
ParameterizedThreadStart start = delegate(object obj) { };
同步上下文 SynchronizationContext
主要用在桌面UI應用 Send(同步) or Post(非同步)
# EAP 非同步操作模式
.NET 3.5
拉姆達表示式
泛型委託 Action 無返回結果,Func 最後必須結果
Action a1 = new Action(() => { });
Action<string> a2 = new Action<string>((s) => { });
Func<string> f1 = new Func<string>(() => { return ""; });
Func<int, string> f2 = new Func<int, string>((n) => { return n.ToString(); });
.NET 4.0
執行緒池執行緒最大數量,是根據電腦記憶體來計算的
優化執行緒池工作項排序
在 .net 4.0 以前,執行緒池的工作項,採用連結串列排隊
現在CPU都是多核處理器,假設現在有很多工作項
出現的問題:
(1)連結串列結構會存在很多引用,對垃圾回收影響很大
(2)連結串列是按順序操作,多核CPU真正的併發受到影響
在 .net 4.0 重新設計工作項排隊結構
陣列+連結串列
陣列元素對應工作項引用
(1)引用減少了
(2)現在是運算元組元素
# TPL 非同步操作模式
5.2 非同步操作模式
(1)APM 模式 Asynchronous Programming Model
2個方法 Begin/End,1個 IAsyncResult
必須呼叫 End,即使不需要返回結果,因為 End 會把執行緒的異常丟擲來
呼叫 End 加 try/catch
呼叫 Begin 之後,應當避免直接呼叫 End,因為 End 會等待結果,可能無限等待
APM 獲取結果
(1)輪詢是否完成
主要使用 System.Windows.Forms.Timer
輪詢 IAsyncResult 的 IsCompleted,並呼叫 End 獲取結果
(2)等待完成,IAsyncResult 的 AsyncWaitHandle 可以設定超時
直接呼叫 End,可能因為執行緒死鎖等,無限等待
使用 AsyncWaitHandle 可以設定超時,但是超時了就不會呼叫 End
不呼叫 End 就意味著執行緒的,異常可能沒捕獲,資源可能洩露
所以 AsyncWaitHandle 並不完美
(3)完成時回撥,AsyncCallback
這裡有個問題,就是回撥並不是在UI執行緒,如果要更新UI控制元件,那就不可以
static void Main(string[] args)
{
HelloDelegate helloDelegate = new HelloDelegate(Hello);
helloDelegate.BeginInvoke(Callback, helloDelegate);
Console.ReadLine();
}
static void Callback(IAsyncResult ar)
{
HelloDelegate helloDelegate = ar.AsyncState as HelloDelegate;
try
{
string s = helloDelegate.EndInvoke(ar);
Console.WriteLine(s);
}
catch (Exception) { }
}
static string Hello()
{
return "hello";
}
public delegate string HelloDelegate();
APM 其他事
.NET 框架的一些類已經實現了 APM 模式
例如:使用 I/O thread 的 WebRequest,Stream,Socket,SqlCommand,MessageQueue 等
委託內在支援 APM 模式,使用(worker thread)
(2)EAP 模式 Event-Based Asynchronous Pattern
1個非同步Async方法,1個Completed事件
static void Main(string[] args)
{
WebClient webClient = new WebClient();
webClient.DownloadDataCompleted += delegate(object sender, DownloadDataCompletedEventArgs e)
{
try
{
byte[] result = e.Result;
}
catch (Exception) { }
};
webClient.DownloadDataAsync(new Uri(""));
}
在獲取 Result 的時候, try/catch
EAP 有個問題,如果發起多個非同步請求,在完成事件裡,需要區分結果來自哪個非同步操作呢
(3)TPL 模式 Task Parallel Library
基於 System.Threading.Tasks.Task
實現標準的取消執行緒,報告執行緒進度操作
Task 本質代表未來的操作
Task task = new Task(() =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
throw new Exception("error");
});
task.Start();
task.ContinueWith((t) =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(t.Exception.InnerException.Message);
}, TaskContinuationOptions.OnlyOnFaulted);
Console.ReadLine();
相關文章
- 多執行緒(五)---執行緒的Yield方法執行緒
- .net使用Task多執行緒執行任務 .net限制執行緒數量執行緒
- .NET Core 中使用多執行緒或非同步操作來實現分片下載執行緒非同步
- 多執行緒之ReentrantLock篇(五)執行緒ReentrantLock
- Java多執行緒(五):死鎖Java執行緒
- 非同步/同步,阻塞/非阻塞,單執行緒/多執行緒概念梳理非同步執行緒
- 多執行緒和多執行緒同步執行緒
- 伺服器模型——從單執行緒阻塞到多執行緒非阻塞(下)伺服器模型執行緒
- 伺服器模型——從單執行緒阻塞到多執行緒非阻塞(中)伺服器模型執行緒
- 多執行緒--執行緒管理執行緒
- 執行緒與多執行緒執行緒
- 多執行緒【執行緒池】執行緒
- Java多執行緒-執行緒中止Java執行緒
- 多執行緒之初識執行緒執行緒
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- playwright非同步操作-多標籤執行非同步
- 多執行緒系列(1),多執行緒基礎執行緒
- a、多執行緒執行緒
- Java多執行緒學習(五)執行緒間通訊知識點補充Java執行緒
- 多執行緒系列之 執行緒安全執行緒
- iOS 多執行緒之執行緒安全iOS執行緒
- Java多執行緒之執行緒中止Java執行緒
- Android多執行緒之執行緒池Android執行緒
- Java多執行緒-執行緒狀態Java執行緒
- Java多執行緒-執行緒通訊Java執行緒
- kuangshenshuo-多執行緒-執行緒池執行緒
- java 多執行緒守護執行緒Java執行緒
- Java多執行緒(2)執行緒鎖Java執行緒
- 多執行緒之手撕執行緒池執行緒
- java多執行緒9:執行緒池Java執行緒
- 【java多執行緒】(二)執行緒停止Java執行緒
- 執行緒以及多執行緒,多程式的選擇執行緒
- 多執行緒學習一(多執行緒基礎)執行緒
- Java多執行緒(一)多執行緒入門篇Java執行緒
- 多執行緒,多程式執行緒
- 【多執行緒總結(二)-執行緒安全與執行緒同步】執行緒
- 使用委託開啟多執行緒(多執行緒深入)執行緒
- 【Java多執行緒】輕鬆搞定Java多執行緒(二)Java執行緒
- 【Java多執行緒】執行緒安全的集合Java執行緒