下面的代码开始计数,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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
您的令牌已断开连接CancellationTokenSource:
CancellationTokenSource src1 = new CancellationTokenSource();
CancellationToken tkn1 = new CancellationToken();
Run Code Online (Sandbox Code Playgroud)
如您所见 - 您只需创建新的令牌而不与源有任何关系.因此,当您请求取消令牌源时 - 它不会以任何方式影响该令牌.而不是创建新的令牌 - 从源使用令牌:
CancellationToken tkn1 = src1.Token;
Run Code Online (Sandbox Code Playgroud)
请注意,此处还存在竞争条件:
var task1 = Task.Run(() => Count(tkn1), tkn1);
var task2 = Task.Run(() => Stop(src1));
task2.Wait();
Run Code Online (Sandbox Code Playgroud)
在等待task2该过程立即退出之后,您正在等待完成.task2是请求令牌取消的任务.取消令牌后,您的循环可能需要长达80毫秒(根据您的代码)注意并写入消息.在此之前 - 进程可能已经退出,您将看不到任何消息.为了避免这种情况 - 等待task1(实际循环)完成:
var task1 = Task.Run(() => Count(tkn1), tkn1);
var task2 = Task.Run(() => Stop(src1));
task1.Wait();
Run Code Online (Sandbox Code Playgroud)