C#取消正在運行的Task


更新記錄
本文遷移自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();
                }
            }
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM