成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

使用Task代替ThreadPool和Thread

GPS平臺(tái)、網(wǎng)站建設(shè)、軟件開(kāi)發(fā)、系統(tǒng)運(yùn)維,找森大網(wǎng)絡(luò)科技!
http://cnsendnet.taobao.com
來(lái)自森大科技官方博客
http://www.cnsendblog.com/index.php/?p=435

創(chuàng)新互聯(lián)建站主營(yíng)滑縣網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,app軟件開(kāi)發(fā),滑縣h5重慶小程序開(kāi)發(fā)公司搭建,滑縣網(wǎng)站營(yíng)銷推廣歡迎滑縣等地區(qū)企業(yè)咨詢

一:Task的優(yōu)勢(shì)

ThreadPool相比Thread來(lái)說(shuō)具備了很多優(yōu)勢(shì),但是ThreadPool卻又存在一些使用上的不方便。比如:

1: ThreadPool不支持線程的取消、完成、失敗通知等交互性操作;

2: ThreadPool不支持線程執(zhí)行的先后次序;

以往,如果開(kāi)發(fā)者要實(shí)現(xiàn)上述功能,需要完成很多額外的工作,現(xiàn)在,F(xiàn)CL中提供了一個(gè)功能更強(qiáng)大的概念:Task。Task在線程池的基礎(chǔ)上進(jìn)行了優(yōu)化,并提供了更多的API。在FCL4.0中,如果我們要編寫多線程程序,Task顯然已經(jīng)優(yōu)于傳統(tǒng)的方式。

以下是一個(gè)簡(jiǎn)單的任務(wù)示例:

staticvoid Main(string[] args)
{
Task t =new Task(() =>
{
Console.WriteLine("任務(wù)開(kāi)始工作……");
//模擬工作過(guò)程
Thread.Sleep(5000);
});
t.Start();
t.ContinueWith((task) =>
{
Console.WriteLine("任務(wù)完成,完成時(shí)候的狀態(tài)為:");
Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted);
});
Console.ReadKey();
}

二:Task的完成狀態(tài)

任務(wù)Task有這樣一些屬性,讓我們查詢?nèi)蝿?wù)完成時(shí)的狀態(tài):

1: IsCanceled,因?yàn)楸蝗∠瓿桑?/p>

2: IsCompleted,成功完成;

3: IsFaulted,因?yàn)榘l(fā)生異常而完成

需要注意的是,任務(wù)并沒(méi)有提供回調(diào)事件來(lái)通知完成(像BackgroundWorker一樣),它通過(guò)啟用一個(gè)新任務(wù)的方式來(lái)完成類似的功能。ContinueWith方法可以在一個(gè)任務(wù)完成的時(shí)候發(fā)起一個(gè)新任務(wù),這種方式天然就支持了任務(wù)的完成通知:我們可以在新任務(wù)中獲取原任務(wù)的結(jié)果值。

   下面是一個(gè)稍微復(fù)雜一點(diǎn)的例子,同時(shí)支持完成通知、取消、獲取任務(wù)返回值等功能:
staticvoid Main(string[] args)
{
CancellationTokenSource cts =new CancellationTokenSource();
Task<int> t =new Task<int>(() => Add(cts.Token), cts.Token);
t.Start();
t.ContinueWith(TaskEnded);
//等待按下任意一個(gè)鍵取消任務(wù)
Console.ReadKey();
cts.Cancel();
Console.ReadKey();
}

staticvoid TaskEnded(Task<int> task)
{
Console.WriteLine("任務(wù)完成,完成時(shí)候的狀態(tài)為:");
Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted);
Console.WriteLine("任務(wù)的返回值為:{0}", task.Result);
}

staticint Add(CancellationToken ct)
{
Console.WriteLine("任務(wù)開(kāi)始……");
int result =0;
while (!ct.IsCancellationRequested)
{
result++;
Thread.Sleep(1000);
}
return result;
}

在任務(wù)開(kāi)始后大概3秒鐘的時(shí)候按下鍵盤,會(huì)得到如下的輸出:

任務(wù)開(kāi)始……
任務(wù)完成,完成時(shí)候的狀態(tài)為:
IsCanceled=False IsCompleted=True IsFaulted=False
任務(wù)的返回值為:3
你也許會(huì)奇怪,我們的任務(wù)是通過(guò)Cancel的方式處理,為什么完成的狀態(tài)IsCanceled那一欄還是False。這是因?yàn)樵诠ぷ魅蝿?wù)中,我們對(duì)于IsCancellationRequested進(jìn)行了業(yè)務(wù)邏輯上的處理,并沒(méi)有通過(guò)ThrowIfCancellationRequested方法進(jìn)行處理。如果采用后者的方式,如下:

staticvoid Main(string[] args)
{
CancellationTokenSource cts =new CancellationTokenSource();
Task<int> t =new Task<int>(() => AddCancleByThrow(cts.Token), cts.Token);
t.Start();
t.ContinueWith(TaskEndedByCatch);
//等待按下任意一個(gè)鍵取消任務(wù)
Console.ReadKey();
cts.Cancel();
Console.ReadKey();
}

staticvoid TaskEndedByCatch(Task<int> task)
{
Console.WriteLine("任務(wù)完成,完成時(shí)候的狀態(tài)為:");
Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted);
try
{
Console.WriteLine("任務(wù)的返回值為:{0}", task.Result);
}
catch (AggregateException e)
{
e.Handle((err) => err is OperationCanceledException);
}
}

staticint AddCancleByThrow(CancellationToken ct)
{
Console.WriteLine("任務(wù)開(kāi)始……");
int result =0;
while (true)
{
ct.ThrowIfCancellationRequested();
result++;
Thread.Sleep(1000);
}
return result;
}

那么輸出為:

任務(wù)開(kāi)始……
任務(wù)完成,完成時(shí)候的狀態(tài)為:
IsCanceled=True IsCompleted=True IsFaulted=False
在任務(wù)結(jié)束求值的方法TaskEndedByCatch中,如果任務(wù)是通過(guò)ThrowIfCancellationRequested方法結(jié)束的,對(duì)任務(wù)求結(jié)果值將會(huì)拋出異常OperationCanceledException,而不是得到拋出異常前的結(jié)果值。這意味著任務(wù)是通過(guò)異常的方式被取消掉的,所以可以注意到上面代碼的輸出中,狀態(tài)IsCancled為True。

再一次,我們注意到取消是通過(guò)異常的方式實(shí)現(xiàn)的,而表示任務(wù)中發(fā)生了異常的IsFaulted狀態(tài)卻還是等于False。這是因?yàn)門hrowIfCancellationRequested是協(xié)作式取消方式類型CancellationTokenSource的一個(gè)方法,CLR進(jìn)行了特殊的處理。CLR知道這一行程序開(kāi)發(fā)者有意為之的代碼,所以不把它看作是一個(gè)異常(它被理解為取消)。要得到IsFaulted等于True的狀態(tài),我們可以修改While循環(huán),模擬一個(gè)異常出來(lái):

while (true)
{
//ct.ThrowIfCancellationRequested();
if (result ==5)
{
thrownew Exception("error");
}
result++;
Thread.Sleep(1000);
}

模擬異常后的輸出為:

任務(wù)開(kāi)始……
任務(wù)完成,完成時(shí)候的狀態(tài)為:
IsCanceled=False IsCompleted=True IsFaulted=True

三:任務(wù)工廠

Task還支持任務(wù)工廠的概念。任務(wù)工廠支持多個(gè)任務(wù)之間共享相同的狀態(tài),如取消類型CancellationTokenSource就是可以被共享的。通過(guò)使用任務(wù)工廠,可以同時(shí)取消一組任務(wù):

staticvoid Main(string[] args)
{
CancellationTokenSource cts =new CancellationTokenSource();
//等待按下任意一個(gè)鍵取消任務(wù)
TaskFactory taskFactory =new TaskFactory();
Task[] tasks =new Task[]
{
taskFactory.StartNew(() => Add(cts.Token)),
taskFactory.StartNew(() => Add(cts.Token)),
taskFactory.StartNew(() => Add(cts.Token))
};
//CancellationToken.None指示TasksEnded不能被取消
taskFactory.ContinueWhenAll(tasks, TasksEnded, CancellationToken.None);
Console.ReadKey();
cts.Cancel();
Console.ReadKey();
}

staticvoid TasksEnded(Task[] tasks)
{
Console.WriteLine("所有任務(wù)已完成!");
}

以上代碼輸出為:

任務(wù)開(kāi)始……
任務(wù)開(kāi)始……
任務(wù)開(kāi)始……
所有任務(wù)已完成(取消)!
本建議演示了Task(任務(wù))和TaskFactory(任務(wù)工廠)的使用方法。Task甚至進(jìn)一步優(yōu)化了后臺(tái)線程池的調(diào)度,加快了線程的處理速度。在FCL4.0時(shí)代,使用多線程,我們理應(yīng)更多地使用Task。

GPS平臺(tái)、網(wǎng)站建設(shè)、軟件開(kāi)發(fā)、系統(tǒng)運(yùn)維,找森大網(wǎng)絡(luò)科技!
http://cnsendnet.taobao.com
來(lái)自森大科技官方博客
http://www.cnsendblog.com/index.php/?p=435

本文名稱:使用Task代替ThreadPool和Thread
鏈接URL:http://jinyejixie.com/article0/ghhdio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、自適應(yīng)網(wǎng)站App設(shè)計(jì)、商城網(wǎng)站面包屑導(dǎo)航、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
新郑市| 类乌齐县| 乡城县| 临猗县| 大渡口区| 房产| 瑞丽市| 永寿县| 乐业县| 闽侯县| 高安市| 河北区| 营山县| 榆树市| 房产| 宜春市| 神池县| 邵东县| 绥芬河市| 宣汉县| 布尔津县| 紫阳县| 拜泉县| 阳东县| 屏东市| 铅山县| 虞城县| 江陵县| 滕州市| 丰顺县| 修文县| 汝城县| 丘北县| 达州市| 潍坊市| 密云县| 前郭尔| 绥德县| 墨脱县| 兰西县| 宕昌县|