When I use CancelAfter(), the Task is still running

后端 未结 3 1292
[愿得一人]
[愿得一人] 2021-01-13 20:31

I want to use CancellationTokenSource stop the Task. My tests as follow:

Test 1 : Using Cancel() stopped the task sucessfully.

Test 2 : Using CancelAfter() d

3条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-13 21:21

    The core problem is the Task won't stop once it is started.

    It must be check the IsCancellationRequested.

    There is one way to solve this problem:

    when task is running , use Thread.CurrentThread to get the thread, and create a new Task to listen the running task's CancellationToken. In the listening function:listening the status of cancel, call thread.Abort() if cancel event is ture. Use Abort() is a unsafe way,but it can stop the task.

    The code as follow:

        static void Main(string[] args)
        {
            // If the task running used 3000ms, stop.
            int timeOut = 3000;
            CancellationTokenSource source = new CancellationTokenSource();
            source.CancelAfter(timeOut);
            CancellationToken token = source.Token;
            token.Register(() =>
            {
                Console.WriteLine("Task Is TimeOut!!!!! Stop");
            });
            //start the task:
            Task.Run(() =>
            {
                Console.WriteLine("Task start");
                Thread thread = Thread.CurrentThread;
                //create a new task listening the token;
                Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("Listening start");
                    while (!token.IsCancellationRequested)
                    {
                        Console.WriteLine("Listening...");
                        Thread.Sleep(800);
                    }
                    Console.WriteLine("Listening End");
                    thread.Abort();
                }, token);
    
                Stopwatch time = Stopwatch.StartNew();
                #region A long time operation:;
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("run...");
                    Thread.Sleep(100);
                }
                #endregion
                time.Stop();
                Console.WriteLine("Task end. cost:{0}", time.ElapsedMilliseconds);
                source.Cancel();
                Console.WriteLine("Task End");
                token.ThrowIfCancellationRequested();
            }, token);
            Console.ReadLine();
        }
    

提交回复
热议问题