为什么在令牌未取消的情况下注册代表会解雇?

问题描述

我试图了解使用CancellationTokens并收听它们。我发现了一些示例,这些示例显示了如何注册侦听器,但是即使未取消该进程,它仍然会触发。

我的通话测试方法:

    private static void TestRun2()
    {
        var cts = new CancellationTokenSource();  
        try
        {
            var options = new ParallelOptions
            {
                CancellationToken = cts.Token,};

            Parallel.Invoke(options,() => TestMethod(cts.Token));

            cts.Cancel();
            cts.Dispose();

        }
        catch (OperationCanceledException ex)
        {
            cts.Cancel();
            cts.Dispose();
            Console.WriteLine("Timeout");
        }
    }

注册了CancellationToken的相关方法:

    private static void TestMethod(CancellationToken token)
    {
        var wc = new WebClient();
        wc.DownloadStringCompleted += (s,e) => Console.WriteLine("GetWebData: Request completed.");

        // Cancellation on the token will
        // call CancelAsync on the WebClient.
        token.Register(() =>
        {
            wc.CancelAsync();
            Console.WriteLine("GetWebData: Request cancelled!");
        });

        Console.WriteLine("GetWebData: Starting request.");
        wc.DownloadStringAsync(new Uri("http://www.microsoft.com"));
    }

当我强制取消时,它似乎可以工作...但是,当我不这样做时,仍然会调用该委托,并且我会在控制台上收到有关取消请求的通知。我环顾四周,却看不到为什么会不断发生这种情况的任何解释。

所以问题是为什么为什么在未取消请求时显示请求已取消?

解决方法

让我们看看这个:

Parallel.Invoke(options,() => TestMethod(cts.Token));

cts.Cancel();
cts.Dispose();

您开除TestMethod。 TestMethod是异步的。它将立即返回。然后紧接着,您致电cts.Cancel()发出取消信号。

它正在按设计工作。将您的回调更改为此:

wc.DownloadStringCompleted += (s,e) =>
    Console.WriteLine($"GetWebData: Request completed. Cancelled: {e.Cancelled}");

它将输出:

GetWebData: Request completed. Cancelled: True

为了更好地说明我的观点,请尝试执行以下操作:

Parallel.Invoke(options,() => TestMethod(cts.Token));

Thread.Sleep(5000);

cts.Cancel();
cts.Dispose();

很明显,您不应该在最终实现中执行此操作,而只是出于演示目的。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...