当取消请求返回true时如何执行某项操作?

3

以下代码开始计数,3秒后将打印“i”变量的值。 程序打印了变量,但它没有按照我想要的样式打印。在 if (token.IsCancellationRequested) 部分下,它不打印 Console.Writeline 语句。我认为当取消请求为 true 时,程序直接退出。是否可能在取消请求为 true 时打印出 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个回答

5

您的令牌已从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();

很奇怪。当我使用Console.Readline()代替Task2.Wait()时,我也可以得到我想要的输出。也许我不应该等待Task2?你觉得呢? - Lyrk
如果我不等待Task2,它就不会打印任何东西。 - Lyrk
@Lyrk 我已经更新了有关那个的信息。 - Evk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接