Nor*_*gul 0 c# multithreading asynchronous task cancellationtokensource
我在掌握任务和取消令牌方面遇到了一些问题.我做了一个看起来像这样的程序:
static void Main(string[] args)
{
CancellationTokenSource token = new CancellationTokenSource();
Stopwatch stop = new Stopwatch();
stop.Start();
for (int i = 0; i < 5; i++)
{
//Thread.Sleep(1000);
Task.Factory.StartNew(() => myLongTask(token.Token, (i + 1) * 1000));
}
while (true)
{
Thread.SpinWait(1000);
if (stop.ElapsedMilliseconds > 3000)
{
token.Cancel();
}
}
}
public static void myLongTask(CancellationToken token, int time)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancelled");
return;
}
var sw = Stopwatch.StartNew();
Console.WriteLine($"Task {time / 1000} started");
while (sw.ElapsedMilliseconds < time)
Thread.SpinWait(1000);
Console.WriteLine($"Task {time / 1000} ended");
}
Run Code Online (Sandbox Code Playgroud)
我同时运行5个任务(虽然我不包括Thread.Sleep()的for循环似乎运行之前,任务甚至开始?).运行程序时,没有任何任务被取消.还有什么让我烦恼的是......我在打电话时取消了什么token.Cancel()?如何选择杀死5项任务中的哪一项?我可以通过它的变量来定义每个任务,但是CancellationRequested由于它被触发,我无法访问它的属性CancellationToken.我需要5个不同的令牌吗?
运行程序时,没有任何任务被取消.
那是因为你只是在任务开始时检查取消令牌.一旦它超过第一次token.IsCancellationRequested检查,取消令牌什么都不做.如果您将支票移入您的循环,如下所示:
while (sw.ElapsedMilliseconds < time)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancelled");
return;
}
Thread.SpinWait(1000);
}
Run Code Online (Sandbox Code Playgroud)
...然后你会看到任务反应得当.
还有什么让我烦恼的是......我在打电话时取消了什么
token.Cancel()?
您没有取消任务 - 您取消了取消令牌.任何观察取消令牌的任务都将被取消(或完成,或采取任何行动),但任务和令牌之间没有直接关联.
当我们谈论"取消任务"时,我们的意思是"取消我们认为任务正在观察的令牌".