.NET 并行(多核)编程系列之六 Task基础部分完结篇
.NET 并行(多核)編程系列之六 Task基礎(chǔ)部分完結(jié)篇
前言:之前的文章介紹了了并行編程的一些基本的,也注重的講述了Task的一些使用方法,本篇很短,將會結(jié)束Task的基礎(chǔ)知識的介紹。
?
本篇的主要議題如下:
1.?????? 獲取Task的狀態(tài)
2.?????? 執(zhí)行晚加載的Task(Lazily Task)
3.?????? 常見問題的解決方案
?
系列文章鏈接:
.NET 4 并行(多核)編程系列之一入門介紹
.NET 4 并行(多核)編程系列之二 從Task開始?
.NET 4 并行(多核)編程系列之三 從Task的取消?
.NET 4 并行(多核)編程系列之四 Task的休眠?
.NET 并行(多核)編程系列之五 Task執(zhí)行和異常處理?
.NET 并行(多核)編程系列之六 Task基礎(chǔ)部分完結(jié)篇?
.NET 并行(多核)編程系列之七 共享數(shù)據(jù)問題和解決概述
?
1.?????? 獲取Task的狀態(tài)
??????? 在.NET并行編程還有一個已經(jīng)標準化的操作就是可以獲取task的狀態(tài),通過Task.Status屬性來得到的,這個屬性返回一個System.Threading.Tasks.TaskStatus的枚舉值。
如下:
?????? Created:表明task已經(jīng)被初始化了,但是還沒有加入到Scheduler中。
?????? WatingForActivation:task正在等待被加入到Scheduler中。
?WaitingToRun:已經(jīng)被加入到了Scheduler,等待執(zhí)行。
?????? Running:task正在運行
?????? WaitingForChildrenToComplete:表明父task正在等待子task運行結(jié)束。
?????? RanToCompletion:表明task已經(jīng)執(zhí)行完了,但是還沒有被cancel,而且也這個task也沒有拋出異常。
?????? Canceled:表明task已經(jīng)被cancel了。(大家可以參看之前講述取消task的文章)
?????? Faulted:表明task在運行的時候已經(jīng)拋出了異常。
?
2.?????? 執(zhí)行晚加載的Task(Lazily Task)
晚加載,或者又名延遲初始化,主要的好處就是避免不必要的系統(tǒng)開銷。在并行編程中,可以聯(lián)合使用Lazy變量和Task<>.Factory.StartNew()做到這點。(Lazy變量時.NET 4中的一個新特性,這里大家不用知道Lazy的具體細節(jié))
?????? Lazy變量只有在用到的時候才會被初始化。所以我們可以把Lazy變量和task的創(chuàng)建結(jié)合:只有這個task要被執(zhí)行的時候才去初始化。
?????? 下面還是通過例子來講解:?
?
代碼 ??static?void?Main(string[]?args)????????{
????????????//?define?the?function
????????????Func<string>?taskBody?=?new?Func<string>(()?=>
????????????{
????????????????Console.WriteLine("Task?body?working...");
????????????????return?"Task?Result";
????????????});
????????????//?create?the?lazy?variable
????????????Lazy<Task<string>>?lazyData?=?new?Lazy<Task<string>>(()?=>
????????????Task<string>.Factory.StartNew(taskBody));
????????????Console.WriteLine("Calling?lazy?variable");
????????????Console.WriteLine("Result?from?task:?{0}",?lazyData.Value.Result);
????????????//?do?the?same?thing?in?a?single?statement
????????????Lazy<Task<string>>?lazyData2?=?new?Lazy<Task<string>>(
????????????()?=>?Task<string>.Factory.StartNew(()?=>
????????????{
????????????????Console.WriteLine("Task?body?working...");
????????????????return?"Task?Result";
????????????}));
????????????Console.WriteLine("Calling?second?lazy?variable");
????????????Console.WriteLine("Result?from?task:?{0}",?lazyData2.Value.Result);
????????????//?wait?for?input?before?exiting
????????????Console.WriteLine("Main?method?complete.?Press?enter?to?finish.");
????????????Console.ReadLine();
????????}
?
??????
首先我們回想一下,在之前的系列文章中我們是怎么定義一個task的:直接new,或者通過task的factory來創(chuàng)建,因為創(chuàng)建task的代碼是在main函數(shù)中的,所以只要new了一個task,那么這個task就被初始化。現(xiàn)在如果用了Lazy的task,那么現(xiàn)在我們初始化的就是那個Lazy變量了,而沒有初始化task,(初始化Lazy變量的開銷小于初始化task),只有當調(diào)用了lazyData.Value時,Lazy變量中包含的那個task才會初始化。(這里歡迎大家提出自己的理解)?
?
3.?????? 常見問題的解決方案
a.?????? Task 死鎖
描述:如果有兩個或者多個task(簡稱TaskA)等待其他的task(TaskB)執(zhí)行完成才開始執(zhí)行,但是TaskB也在等待TaskA執(zhí)行完成才開始執(zhí)行,這樣死鎖就產(chǎn)生了。
?
解決方案:避免這個問題最好的方法就是:不要使的task來依賴其他的task。也就是說,最好不要你定義的task的執(zhí)行體內(nèi)包含其他的task。
?
例子:在下面的例子中,有兩個task,他們相互依賴:他們都要使用對方的執(zhí)行結(jié)果。當主程序開始運行之后,兩個task也開始運行,但是因為兩個task已經(jīng)死鎖了,所以主程序就一直等待。
?
?
代碼 ??static?void?Main(string[]?args)????????{
????????????//?define?an?array?to?hold?the?Tasks
????????????Task<int>[]?tasks?=?new?Task<int>[2];
????????????//?create?and?start?the?first?task
????????????tasks[0]?=?Task.Factory.StartNew(()?=>
????????????{
????????????????//?get?the?result?of?the?other?task,
????????????????//?add?100?to?it?and?return?it?as?the?result
????????????????return?tasks[1].Result?+?100;
????????????});
????????????//?create?and?start?the?second?task
????????????tasks[1]?=?Task.Factory.StartNew(()?=>
????????????{
????????????????//?get?the?result?of?the?other?task,
????????????????//?add?100?to?it?and?return?it?as?the?result
????????????????return?tasks[1].Result?+?100;
????????????});
????????????//?wait?for?the?tasks?to?complete
????????????Task.WaitAll(tasks);
????????????//?wait?for?input?before?exiting
????????????Console.WriteLine("Main?method?complete.?Press?enter?to?finish.");
????????????Console.ReadLine();
????????}
?
?
? 本篇就到這里了,很短,基礎(chǔ)的部分就基本介紹完了,后面的文章就開始講述應(yīng)用。
? 版權(quán)為小洋和博客園所有,轉(zhuǎn)載請標明出處給作者。
http://www.cnblogs.com/yanyangtian
?
?
?
?
?
?
?
?
?
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的.NET 并行(多核)编程系列之六 Task基础部分完结篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在 Apex 代码中生成 csv 文件
- 下一篇: Jq_网站顶部定时折叠广告