C 並行和多執行緒程式設計四 Task高階

2021-08-21 08:53:29 字數 3588 閱讀 3722

一、task的巢狀task中還可以再巢狀task,thread中能不能這樣做,我只能說我是沒這樣寫過。task中的巢狀,我感覺其實也可以分開來寫,不過巢狀起來會方便管理一點。task中的巢狀分為兩種,關聯巢狀和非關聯巢狀,就是說內層的task和外層的task是否有聯絡,下面我們編寫**先來看一下非關聯巢狀,及內層task和外層task沒有任何關係,還是在控制台程式下面,**如下:

static

void main(string

args)

);console.writeline(

"parent task finished!");

});ptask.wait();

console.writeline(

"flag");

console.read();

}

執行後,輸出以下資訊:

從圖中我們可以看到,外層的ptask執行完後,並不會等待內層的ctask,直接向下走先輸出了flag。這種巢狀有時候相當於我們建立兩個task,但是巢狀在一起的話,在task比較多時會方便查詢和管理,並且還可以在乙個task中途加入多個task,讓進度並行前進。

下面我們來看一下如何建立關聯巢狀,就是建立有父子關係的task,修改上面**如下:

static

void main(string

args)

,taskcreationoptions.attachedtoparent);

console.writeline(

"parent task finished!");

});ptask.wait();

console.writeline(

"flag");

console.read();

}

可以看到,我們在建立ctask時,加入了以引數,taskcreationoptions.attachedtoparent,這個時候,ctask和ptask就會建立關聯,ctask就會成為ptask的一部分,執行**,看下結果:

可以看到,ttask會等待ctask執行完成。省得我們寫task.waitall了,外層的task會自動等待所有的子task完成才向下走。

下面我們來寫乙個task綜合使用的例子,來看一下多工是如何協作的。假設有如下任務,如圖:

任務2和任務3要等待任務1完成後,取得任務1的結果,然後開始執行。任務4要等待任務2完成,取得其結果才能執行,最終任務3和任務4都完成了,合併結果,任務完成。圖中已經說的很明白了。下面來看一下**:

using

system;

using

system.collections.generic;

using

system.linq;

using

system.text;

using

system.threading.tasks;

namespace

taskdemo

); t1.wait();

//等待任務一完成

var t3 = task.factory.startnew(() =>);

var t4 = task.factory.startnew(() =>).continuewith

(task =>);

task.waitall(t3, t4);

//等待任務三和任務四完成

var result = task.factory.startnew(() =>

",t3.result +t4.result);

});});

console.read();}}

}

任務2和任務4可以用continuewith連線執行,最終執行結果如圖:

可以看到所有的任務都執行了,我們也得到了正確的結果11.這**會到task的強大了吧~

二、task的異常處理

任何應用程式都需要有異常處理機制,誰也不能保證自己寫到**在任何時候都是可以正常執行的,那麼在task中到底該怎麼處理異常呢?先來按照平時的寫法,加個try...catch...試試,看看會出現什麼現象:

唉,不對啊~~怎麼顯示這異常資訊呢?先不說異常資訊對不對,反正異常是捕獲到了。從這張圖中你們還發現了什麼嗎?

沒錯,ctask被中斷了,這裡ctask和ptask並沒有建立關聯,但是ptask出現異常,其內部的task也都會中斷,不再執行,即使異常是在子task啟動以後發生的。

下面我們繼續來說異常吧,來看看正確的異常處理辦法,怎麼捕獲到真正的異常資訊,**如下:

static

void main(string

args)

);throw

new exception("

ptask error!");

console.writeline(

"parent task finished!");

});ptask.wait();

}catch

(aggregateexception ex)

}console.writeline(

"flag");

console.read();

}

這裡用了aggregateexception,就是異常集合,當然開發中不會只有乙個執行緒,肯定會有多個執行緒,多個執行緒就可能有多個異常。我們變數異常集合,輸出異常資訊,如下圖:

對了吧,看到正確的異常資訊了,但是還是看不到ctask的,因為他被中斷了。

當然,除了在task中使用異常,我們還可以通過task的幾個屬性來判斷task的狀態,如:iscompleted, isfaulted, iscancelled,exception等等來判斷task是否成功的執行了。

Task多執行緒並行開發

net 4.0之後出現的多執行緒物件。task 其實時thread 和threadpool的結合和優化 thread 通過windbg觀察執行完後gc下次 時間空間開銷不小,呼叫過多時間片切換頻繁影響效率 threadpool 受限cpu核心執行緒數,clr控制 task使用方法 new乙個新的ta...

C 多執行緒程式設計(1) 執行緒,執行緒池和Task

新開了乙個多執行緒程式設計系列,該系列主要講解c 中的多執行緒程式設計。利用多執行緒的目的有2個 一是防止ui執行緒被耗時的程式占用,導致介面卡頓 二是能夠利用多核cpu的資源,提高執行效率。我沒有進行很深入的講解,是以實際使用為主。我的這個系列主要是 clr via c 的總結,該書的作者jeff...

c 並行和多執行緒程式設計 認識Parallel

隨著多核時代的到來,並行開發越來越展示出它的強大威力!使用並行程式,充分的利用系統資源,提高程式的效能。在.net 4.0中,微軟給我們提供了乙個新的命名空間 system.threading.tasks。這裡面有很多關於並行開發的東西,今天第一篇就介紹下最基礎,最簡單的 認識和使用parallel...