新聞中心
查看本系列其他文章,請(qǐng)參看

成都一家集口碑和實(shí)力的網(wǎng)站建設(shè)服務(wù)商,擁有專業(yè)的企業(yè)建站團(tuán)隊(duì)和靠譜的建站技術(shù),10年企業(yè)及個(gè)人網(wǎng)站建設(shè)經(jīng)驗(yàn) ,為成都近1000家客戶提供網(wǎng)頁(yè)設(shè)計(jì)制作,網(wǎng)站開(kāi)發(fā),企業(yè)網(wǎng)站制作建設(shè)等服務(wù),包括成都營(yíng)銷型網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),同時(shí)也為不同行業(yè)的客戶提供網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì)的服務(wù),包括成都電商型網(wǎng)站制作建設(shè),裝修行業(yè)網(wǎng)站制作建設(shè),傳統(tǒng)機(jī)械行業(yè)網(wǎng)站建設(shè),傳統(tǒng)農(nóng)業(yè)行業(yè)網(wǎng)站制作建設(shè)。在成都做網(wǎng)站,選網(wǎng)站制作建設(shè)服務(wù)商就選創(chuàng)新互聯(lián)公司。
[[11863]]
本篇的主要議題如下:
1.獲取Task的狀態(tài)
2.執(zhí)行晚加載的Task(Lazily Task)
3.常見(jiàn)問(wèn)題的解決方案
1.獲取Task的狀態(tài)
在.NET并行編程還有一個(gè)已經(jīng)標(biāo)準(zhǔn)化的操作就是可以獲取task的狀態(tài),通過(guò)Task.Status屬性來(lái)得到的,這個(gè)屬性返回一個(gè)System.Threading.Tasks.TaskStatus的枚舉值。
如下:
Created:表明task已經(jīng)被初始化了,但是還沒(méi)有加入到Scheduler中。
WatingForActivation:task正在等待被加入到Scheduler中。
WaitingToRun:已經(jīng)被加入到了Scheduler,等待執(zhí)行。
Running:task正在運(yùn)行
WaitingForChildrenToComplete:表明父task正在等待子task運(yùn)行結(jié)束。
RanToCompletion:表明task已經(jīng)執(zhí)行完了,但是還沒(méi)有被cancel,而且也這個(gè)task也沒(méi)有拋出異常。
Canceled:表明task已經(jīng)被cancel了。(大家可以參看之前講述取消task的文章)
Faulted:表明task在運(yùn)行的時(shí)候已經(jīng)拋出了異常。
2.執(zhí)行晚加載的Task(Lazily Task)
晚加載,或者又名延遲初始化,主要的好處就是避免不必要的系統(tǒng)開(kāi)銷。在并行編程中,可以聯(lián)合使用Lazy變量和Task<>.Factory.StartNew()做到這點(diǎn)。(Lazy變量時(shí).NET 4中的一個(gè)新特性,這里大家不用知道Lazy的具體細(xì)節(jié))
Lazy變量只有在用到的時(shí)候才會(huì)被初始化。所以我們可以把Lazy變量和task的創(chuàng)建結(jié)合:只有這個(gè)task要被執(zhí)行的時(shí)候才去初始化。
下面還是通過(guò)例子來(lái)講解:
代碼
- static void Main(string[] args)
- {
- // define the function
- Func
taskBody = new Func (() => - {
- Console.WriteLine("Task body working...");
- return "Task Result";
- });
- // create the lazy variable
- Lazy
> lazyData = new Lazy >(() => - Task
.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
> lazyData2 = new Lazy >( - () => Task
.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();
- }
首先我們回想一下,在之前的系列文章中我們是怎么定義一個(gè)task的:直接new,或者通過(guò)task的factory來(lái)創(chuàng)建,因?yàn)閯?chuàng)建task的代碼是在main函數(shù)中的,所以只要new了一個(gè)task,那么這個(gè)task就被初始化?,F(xiàn)在如果用了Lazy的task,那么現(xiàn)在我們初始化的就是那個(gè)Lazy變量了,而沒(méi)有初始化task,(初始化Lazy變量的開(kāi)銷小于初始化task),只有當(dāng)調(diào)用了lazyData.Value時(shí),Lazy變量中包含的那個(gè)task才會(huì)初始化。(這里歡迎大家提出自己的理解)
3.常見(jiàn)問(wèn)題的解決方案
a.Task 死鎖
描述:如果有兩個(gè)或者多個(gè)task(簡(jiǎn)稱TaskA)等待其他的task(TaskB)執(zhí)行完成才開(kāi)始執(zhí)行,但是TaskB也在等待TaskA執(zhí)行完成才開(kāi)始執(zhí)行,這樣死鎖就產(chǎn)生了。
解決方案:避免這個(gè)問(wèn)題最好的方法就是:不要使的task來(lái)依賴其他的task。也就是說(shuō),最好不要你定義的task的執(zhí)行體內(nèi)包含其他的task。
例子:在下面的例子中,有兩個(gè)task,他們相互依賴:他們都要使用對(duì)方的執(zhí)行結(jié)果。當(dāng)主程序開(kāi)始運(yùn)行之后,兩個(gè)task也開(kāi)始運(yùn)行,但是因?yàn)閮蓚€(gè)task已經(jīng)死鎖了,所以主程序就一直等待。
代碼
- static void Main(string[] args)
- {
- // define an array to hold the Tasks
- Task
[] tasks = new Task [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ǔ)的部分就基本介紹完了,后面的文章就開(kāi)始講述應(yīng)用。
網(wǎng)站欄目:.NET 4并行編程之Task基礎(chǔ)部分完結(jié)篇
當(dāng)前網(wǎng)址:http://m.5511xx.com/article/dpesepp.html


咨詢
建站咨詢
