下面的代码开始计数,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();
}
}
}
答案 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();