談多線程談到現在,我們要明確多線程的一個好處是可以進行並行的運算(充分利用多核處理器,對 於桌面應用程序來說就更重要一點了,沒有WEB服務器,利用多核只能靠自己),還有一個好處就是異步 操作,就是我們可以讓某個長時間的操作獨立運行,不妨礙主線程繼續進行一些計算,然後異步的去返回 結果(也可以不返回)。前者能提高性能是因為能利用到多核,而後者能提高性能是因為能讓CPU不在等 待中白白浪費,其實異步從廣義上來說也可以理解為某種並行的運算。在之前的這麼多例子中,我們大多 采用手工方式來新開線程,之前也說過了,在大並發的環境中隨便開始和結束線程的代價太大,需要利用 線程池,使用線程池的話又覺得少了一些控制。現在讓我們來總結一下大概會有哪幾種常見的異步編程應 用模式:
1) 新開一個A線程執行一個任務,然後主線程執行另一個任務後等待線程返回結果後繼續
2) 新開一個A線程執行一個任務,然後主線程不斷輪詢A線程是否執行完畢,如果沒有的話可以選擇 等待或是再進行一些操作
3) 新開一個A線程執行一個任務,執行完畢之後立即執行一個回調方法去更新一些狀態變量,主線程 和A線程不一定有直接交互
4) 新開一個A線程執行一個任務,執行完畢之後啥都不做
(補充一句,異步編程不一定是依賴於線程的,從廣義上來說,使用隊列異步處理數據也可以算是一 種異步編程模式)
對於這任何一種,我們要使用線程池來編寫應用的話都是比較麻煩的,比如如下的代碼實現了1)這種 應用:
class AsyncObj
{
public EventWaitHandle AsyncWaitHandle { get; set; }
public object Result { get; set; }
public AsyncObj()
{
AsyncWaitHandle = new AutoResetEvent(false);
}
}
AsyncObj ao = new AsyncObj();
ThreadPool.QueueUserWorkItem(state =>
{
AsyncObj obj = state as AsyncObj;
Console.WriteLine("asyc operation started @ " + DateTime.Now.ToString ("mm:ss"));
Thread.Sleep(2000);
Console.WriteLine("asyc operation completed @ " + DateTime.Now.ToString ("mm:ss"));
obj.Result = 100;
obj.AsyncWaitHandle.Set();
}, ao);
Console.WriteLine("main operation started @ " + DateTime.Now.ToString("mm:ss"));
Thread.Sleep(1000);
Console.WriteLine("main operation completed @ " + DateTime.Now.ToString ("mm:ss"));
ao.AsyncWaitHandle.WaitOne();
Console.WriteLine("get syc operation result : " + ao.Result.ToString() + " @ " + DateTime.Now.ToString("mm:ss"));
結果如下: