取消请求返回true时如何做sthg?

时间:2017-10-11 12:26:00

标签: c#

下面的代码开始计数,3秒后,它将打印" i"变量。 程序打印变量,但不会以我想要的样式打印。它不会在if(token.IsCancellationRequested)部分下打印Console.Writeline语句。我认为当取消请求为真时,程序会直接退出。当取消请求为真时,我是否可以打印出console.writeline语句?

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication17
{
class Program
{
    private static void Stop(CancellationTokenSource src)
    {
        Thread.Sleep(3000);
        src.Cancel();
    }

    static void Count(CancellationToken token)
    {
        for (int i = 0; i < 100000; i++)
        {
            Console.WriteLine(i);
            Thread.Sleep(80);

            if (token.IsCancellationRequested)
            {
                Console.WriteLine("Current number is :" + i.ToString());
                break;
            }
            else
            {
                Console.Clear();
            }

        }
    }
    static void Main(string[] args)
    {
        CancellationTokenSource src1 = new CancellationTokenSource();
        CancellationToken tkn1 = new CancellationToken();

        var task1 = Task.Run(() => Count(tkn1), tkn1);
        var task2 = Task.Run(() => Stop(src1));
        task2.Wait();

    }
}
}

1 个答案:

答案 0 :(得分:6)

您的令牌已与CancellationTokenSource

断开连接
CancellationTokenSource src1 = new CancellationTokenSource();
CancellationToken tkn1 = new CancellationToken();

如您所见 - 您只需创建新的令牌而与源无任何关系。因此,当您请求取消令牌源时 - 它不会以任何方式影响该令牌。而不是创建新的令牌 - 从源使用令牌:

CancellationToken tkn1 = src1.Token;

请注意,此处还存在竞争条件:

var task1 = Task.Run(() => Count(tkn1), tkn1);
var task2 = Task.Run(() => Stop(src1));
task2.Wait();

您正在等待task2完成,此过程会立即退出。 task2是请求令牌取消的任务。取消令牌后,您的循环可能需要长达80毫秒(根据您的代码)注意并写入消息。在此之前 - 进程可能已经退出,您将看不到任何消息。为避免这种情况 - 请等待task1(实际循环)完成:

 var task1 = Task.Run(() => Count(tkn1), tkn1);
 var task2 = Task.Run(() => Stop(src1));
 task1.Wait();