这是挂起且永不结束的简单代码段:
public static void Main()
{
using (var cancellationTokenSource = new CancellationTokenSource())
{
Console.CancelKeyPress += (_, __) =>
cancellationTokenSource.Cancel();
while (!cancellationTokenSource.Token.WaitHandle.WaitOne(1000))
{
Console.WriteLine("Still running...");
}
Console.WriteLine("Cancellation is requested. Trying to dispose cancellation token...");
}
Console.WriteLine("Just before close");
}
问题是Just before close
行永远不会被执行。我的第一个想法是“也许是因为 KeyPress 关闭”,所以我用以下方式重写了它:
public static void Main()
{
using (var cancellationTokenSource = new CancellationTokenSource())
{
void Foo(object sender, ConsoleCancelEventArgs consoleCancelEventArgs)
{
cancellationTokenSource.Cancel();
}
Console.CancelKeyPress += Foo;
while (!cancellationTokenSource.Token.WaitHandle.WaitOne(1000))
{
Console.WriteLine("Still running...");
}
Console.WriteLine("Cancellation is requested. Unsubscribing...");
Console.CancelKeyPress -= Foo;
Console.WriteLine("Cancellation is requested. Trying to dispose cancellation token...");
}
Console.WriteLine("Just before close");
}
但现在它还挂着Unsubscribing
中风...
知道为什么会这样吗?我想运行一些后台任务并等待它在控制台应用程序中完成,但由于所述原因,我的应用程序刚刚损坏。
问题不在于您的取消令牌,而在于您选择使用CancelKeyPress
。当此事件发生时,您将获得ConsoleCancelEventArgs
,其中有一个Cancel财产:
获取或设置一个值,该值指示是否同时按 Control 修饰键和 C 控制台键 (Ctrl+C) 或 Ctrl+Break 键终止当前进程。默认为 false,即终止当前进程。
由于您没有将其设置为true
,您的应用程序将在事件处理程序完成运行后终止。根据当时具体发生的情况,取消令牌似乎有时有时间脱离 while 循环,有时则没有:
您的原始代码可以修复如下:
public static void Main()
{
using (var cancellationTokenSource = new CancellationTokenSource())
{
Console.CancelKeyPress += (_, ccea) => {
cancellationTokenSource.Cancel();
ccea.Cancel = true; //cancel the cancel. There's too many cancels!
};
while (!cancellationTokenSource.Token.WaitHandle.WaitOne(1000))
{
Console.WriteLine("Still running...");
}
Console.WriteLine("Cancellation is requested. Trying to dispose cancellation token...");
}
Console.WriteLine("Just before close");
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)