我想创建一个控制台应用程序,在使用 Ctrl+C 终止时输出“摘要语句”作为输出的最后一行,但我无法正常工作。这可能部分是由于我尝试创建的应用程序不断地在
while(true)
循环中写入输出。我可以用一个简单的例子来最好地说明问题:
假设我有一个不断输出当前时间的控制台应用程序:
while (true)
{
var now = DateTime.Now;
Console.Write(now);
Console.Write(" ");
Console.Write(now.Millisecond);
Console.CursorLeft = 0; // Overwrite the same line
}
这有效,我可以使用 Ctrl+C 终止应用程序:
23/02/2023 23:07:14 658
现在,当我按下 Ctrl+C 时,我希望文本
Goodbye!
显示为输出的最后一行:
23/02/2023 23:09:56 441
Goodbye!
但是,我无法正常工作。这是我的第一次尝试:
Console.CancelKeyPress += OnCancel;
while (true)
{
var now = DateTime.Now;
Console.Write(now);
Console.Write(" ");
Console.Write(now.Millisecond);
Console.CursorLeft = 0; // Overwrite the same line
}
void OnCancel(object? sender, ConsoleCancelEventArgs e)
{
Console.WriteLine("Goodbye");
}
但是,这会导致“乱码”输出,例如:
Goodbye023 23:14:55 670
23/02/2023 23:14:55
我认为这是因为
Console.CancelKeyPress
事件处理程序在单独的工作线程上执行,并且对 Console.WriteLine("Goodbye");
的调用可以在 while 循环中的任何点发生。理想情况下,CancelKeyPress
事件处理程序在 while
循环的当前迭代完成之前不会运行。我不确定如何以线程安全的方式执行此操作。
我尝试了不同的方法,我不会列出它们的代码,但总而言之,我尝试了以下所有方法都无济于事:
cancelRequested
并设置while
循环条件为!cancelRequested
;在OnCancel
中将var设置为true
;
Console.WriteLine("Goodbye!")
循环后。这阻止了
Console.WriteLine("Goodbye!")
线(死锁?)。CancellationTokenSource
而不是布尔变量。
观察到相同的死锁行为,所以我猜这是等价的?