更新記錄
本文遷移自Panda666原博客,原發布時間:2021年6月29日。
一、說明
Task默認就依托於底層線程池中的線程,使用.NET為我們定義好的CancellationTokenSource類型就可以實現任務的取消。這是標准規范的任務取消操作。
二、非標准不推薦任務取消操作
除了.NET標准的任務取消操作,我們也可以直接進行對任務底層的線程進行中斷,但這是非常不推薦的方式。注意:野蠻的中止線程不是一個好選擇!!!
比如:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Panda666comTest
{
class Program
{
static void Main(string[] args)
{
//新建線程引用
Thread thread = null;
//新建任務
Task t = Task.Run(() =>
{
//獲得當前任務底層的線程的引用
thread = Thread.CurrentThread;
//任務開始
Console.WriteLine("Task start!");
//模擬耗時的操作
Thread.Sleep(1000);
//任務結束
Console.WriteLine("Task finished!");
});
//讓任務先運行起來
Thread.Sleep(10);
//強行終止任務
thread.Abort();
//wait
Console.WriteLine("Success");
Console.ReadKey();
}
}
}
注意:線程對象Abort的方法已經在最新的.NET Core中不被支持!!!
三、標准的任務取消操作
具體流程如下:
新建CancellationTokenSource對象用於輔助任務取消
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationTokenSource類型所在命名空間
using System.Treading;
在具體的任務執行中監視CancellationTokenSource對象的成員,Token的IsCancellationRequested屬性來確定是否需要取消任務,通過任務定期輪詢它,檢查是否發出了取消請求
token.IsCancellationRequested
如果調用.Cancel()發出了取消任務請求,任務立即返回,停止繼續任務
CancellationTokenSource cansrc = new CancellationTokenSource();
cansrc.Cancel();
那我們來把上面那個野蠻終止Task的例子修改一下
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Panda666comTest
{
class Program
{
static void Main(string[] args)
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = tokenSource.Token;
//新建任務
Task t = Task.Run(() =>
{
while(true)
{
//檢測任務是否已經被取消
if(tokenSource.IsCancellationRequested)
{
Console.WriteLine("Task canceled");
break;
}
//任務開始
Console.WriteLine("Task start!");
//模擬耗時的操作
Thread.Sleep(1000);
//任務結束
Console.WriteLine("Task finished!");
}
}, cancellationToken);
Thread.Sleep(10);
//用戶控制是否取消任務
while(true)
{
Console.Write("請切換到英文輸入法");
Console.WriteLine("取消任務請按Y");
if((Console.ReadKey()).Key == ConsoleKey.Y)
{
//任務取消
tokenSource.Cancel();
}
}
}
}
}