C# 使用CancellationTokenSource取消多線程
有時(shí)間我們?cè)谑褂枚嗑€程的時(shí)候,需要取消線程的執(zhí)行,可以使用CancellationTokenSource來(lái)取消對(duì)Task開(kāi)辟多線程的取消
如下:我們點(diǎn)擊一個(gè)按鈕開(kāi)啟線程,然后點(diǎn)擊取消按鈕取消該線程的執(zhí)行

CancellationTokenSource cts ;
/// <summary>
/// 開(kāi)啟線程
/// </summary>
private void button1_Click(object sender, EventArgs e)
{
//重新實(shí)例化cts.Token就會(huì)不一樣,不然再次點(diǎn)擊的時(shí)候會(huì)報(bào)錯(cuò),提示線程已經(jīng)執(zhí)行完畢
cts = new CancellationTokenSource();
Task task = new Task(() =>
{
Thread.Sleep(1500);
try
{
cts.Token.ThrowIfCancellationRequested();
MessageBox.Show("線程被執(zhí)行");
}
catch (Exception ex)
{
MessageBox.Show("線程被取消");
}
}, cts.Token);
task.Start();
//如果放到這里有可能線程還沒(méi)有開(kāi)始執(zhí)行就被取消了
//cts.Cancel(true);
}
/// <summary>
/// 取消線程
/// </summary>
private void button2_Click(object sender, EventArgs e)
{
cts.Cancel();
}

幾點(diǎn)關(guān)鍵問(wèn)題解釋:
1:為什么線程里邊去調(diào)用 Thread.Sleep(1500);
因?yàn)槿绻蛔尵€程暫停一下,你在點(diǎn)擊開(kāi)啟線程后。還沒(méi)有來(lái)得及點(diǎn)擊取消線程,線程都已經(jīng)執(zhí)行完畢了這個(gè)時(shí)候
再去取消線程是沒(méi)有什么意義的。
2: cts.Cancel()
這句話其實(shí)只是設(shè)置一個(gè)狀態(tài),設(shè)置該對(duì)象一個(gè)熟悉為true而已,也就是設(shè)置cts.IsCancellationRequested為ture。
所以他根本沒(méi)有真正的去取消線程的執(zhí)行,只是設(shè)置一個(gè)狀態(tài)而已。
3:cts.Token.ThrowIfCancellationRequested();
因?yàn)樯厦嬲f(shuō)的cts.Cancel()只是設(shè)置一個(gè)狀態(tài)而已,線程不會(huì)真正被取消。其實(shí)線程開(kāi)啟后,現(xiàn)在都是要執(zhí)行完的,
我們并不能真正去取消線程的執(zhí)行,只是從邏輯上去取消線程需要處理的邏輯。
這句話的意思其實(shí)就是檢查cts.Cancel()設(shè)置的屬性狀態(tài),也就是cts.IsCancellationRequested是否為true,如果為
true就拋出一個(gè)異常,從而終止線程的執(zhí)行
也就是說(shuō)其實(shí)這句話完全可以我們自己來(lái)實(shí)現(xiàn)

同時(shí)取消多個(gè)線程:
同時(shí)取消多個(gè)線程,其實(shí)也很簡(jiǎn)單,我們不需要有多少個(gè)線程就去實(shí)例化多少個(gè)CancellationTokenSource,
多個(gè)線程綁定頂一個(gè)CancellationTokenSource的token然后調(diào)用該對(duì)象的cancel就可以同時(shí)取消多個(gè)線程了。
CancellationTokenSource cts;
/// <summary>
/// 開(kāi)啟線程
/// </summary>
private void button1_Click(object sender, EventArgs e)
{
//重新實(shí)例化cts.Token就會(huì)不一樣,不然再次點(diǎn)擊的時(shí)候會(huì)報(bào)錯(cuò),提示線程已經(jīng)執(zhí)行完畢
cts = new CancellationTokenSource();
for (int i = 0; i < 5; i++)
{
Task task = new Task((obj) =>
{
Thread.Sleep(1500);
try
{
//cts.Token.ThrowIfCancellationRequested();
//檢查狀態(tài),檢查線程是否已經(jīng)被取消,如果取消則自己跑出來(lái)一個(gè)線程
if (cts.Token.IsCancellationRequested)
throw new OperationCanceledException();
MessageBox.Show("線程" + obj + "被執(zhí)行");
}
catch (Exception ex)
{
MessageBox.Show("線程" + obj + "被取消");
}
}, i, cts.Token);
task.Start();
}
//如果放到這里有可能線程還沒(méi)有開(kāi)始執(zhí)行就被取消了
//cts.Cancel(true);
}
/// <summary>
/// 取消線程
/// </summary>
private void button2_Click(object sender, EventArgs e)
{
cts.Cancel();
}

到此這篇關(guān)于C# 使用CancellationTokenSource取消多線程的文章就介紹到這了,更多相關(guān)C# 使用CancellationTokenSource取消多線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#從windows剪貼板獲取并顯示文本內(nèi)容的方法
這篇文章主要介紹了C#從windows剪貼板獲取并顯示文本內(nèi)容的方法,涉及C#操作剪貼板的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
在類(lèi)庫(kù)或winform項(xiàng)目中打開(kāi)另一個(gè)winform項(xiàng)目窗體的方法
這篇文章主要介紹了在類(lèi)庫(kù)或winform項(xiàng)目中打開(kāi)另一個(gè)winform項(xiàng)目窗體的方法,可以實(shí)現(xiàn)Winform項(xiàng)目間窗體的調(diào)用,在進(jìn)行Winform項(xiàng)目開(kāi)發(fā)中非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-11-11
ListView Adapter優(yōu)化 實(shí)例
C# 正則表達(dá)式常用的符號(hào)和模式解析(最新推薦)
C#使用jQuery實(shí)現(xiàn)無(wú)刷新評(píng)論提交的方法
C#基于HttpWebRequest實(shí)現(xiàn)發(fā)送HTTP請(qǐng)求的方法分析
c#利用webmail郵件系統(tǒng)發(fā)送郵件示例分享

