为什么这个短程序永远不会完成?
Why does this short program never complete?
通过调试我自己的一个问题,我成功地重新创建了一个行为异常的小程序:
using System;
using System.Threading;
namespace CancelBug
{
class Program
{
static void Main(string[] args)
{
var unused = new ManualResetEvent(false);
var cancelled = new ManualResetEvent(false);
Console.CancelKeyPress += (s, e) => cancelled.Set();
Console.WriteLine("Running. The only thing to do now is ctrl+c or close the window...");
WaitHandle.WaitAny(new[] { unused, cancelled });
Console.WriteLine("Press enter to continue...");
Console.Read();
}
}
}
我希望这个程序:
- 显示第一行
- 等到用户尝试退出程序
- 显示第二行
- 等到用户按下回车
- 退出
但是,一旦它通过了对 WaitHandle.WaitAny
的调用,它似乎就挂在了随机线路上。有时最后一行永远不会被打印,有时它会被打印但回车键永远不会被读取。有了更大的代码库,它可以执行更多行代码,并且仍然挂在看似随机的位置。
谁能解释这种奇怪的行为?
Ctrl + C
是关闭命令window的全局命令。因此,此组合键将在实际程序结束前关闭 window。尝试使用其他密钥。
您需要取消 CTRL+C
命令,否则您的进程将被终止:
Console.CancelKeyPress += (s, e) =>
{
e.Cancel = true;
cancelled.Set();
};
来自https://msdn.microsoft.com/en-us/library/system.consolecanceleventargs(v=vs.110).aspx:
If the Cancel property is set to true in the event handler, the
process is resumed; otherwise, the process is terminated. By default,
the value of the ConsoleCancelEventArgs property is false, and the
process terminates.
请运行 没有调试器的应用程序(直接从命令行)。
根据我的测试,这是我的测试应用程序,它的行为符合您的预期。
var cancelled = new ManualResetEvent(false);
Console.CancelKeyPress += (s, e) =>
{
e.Cancel = true;
Console.WriteLine("Ctrl+C detected...");
cancelled.Set();
};
Console.WriteLine("Running. The only thing to do now is ctrl+c or close the window...");
WaitHandle.WaitAny(new[] { cancelled });
Console.WriteLine("Press enter to exit...");
Console.ReadLine();
通过调试我自己的一个问题,我成功地重新创建了一个行为异常的小程序:
using System;
using System.Threading;
namespace CancelBug
{
class Program
{
static void Main(string[] args)
{
var unused = new ManualResetEvent(false);
var cancelled = new ManualResetEvent(false);
Console.CancelKeyPress += (s, e) => cancelled.Set();
Console.WriteLine("Running. The only thing to do now is ctrl+c or close the window...");
WaitHandle.WaitAny(new[] { unused, cancelled });
Console.WriteLine("Press enter to continue...");
Console.Read();
}
}
}
我希望这个程序:
- 显示第一行
- 等到用户尝试退出程序
- 显示第二行
- 等到用户按下回车
- 退出
但是,一旦它通过了对 WaitHandle.WaitAny
的调用,它似乎就挂在了随机线路上。有时最后一行永远不会被打印,有时它会被打印但回车键永远不会被读取。有了更大的代码库,它可以执行更多行代码,并且仍然挂在看似随机的位置。
谁能解释这种奇怪的行为?
Ctrl + C
是关闭命令window的全局命令。因此,此组合键将在实际程序结束前关闭 window。尝试使用其他密钥。
您需要取消 CTRL+C
命令,否则您的进程将被终止:
Console.CancelKeyPress += (s, e) =>
{
e.Cancel = true;
cancelled.Set();
};
来自https://msdn.microsoft.com/en-us/library/system.consolecanceleventargs(v=vs.110).aspx:
If the Cancel property is set to true in the event handler, the process is resumed; otherwise, the process is terminated. By default, the value of the ConsoleCancelEventArgs property is false, and the process terminates.
请运行 没有调试器的应用程序(直接从命令行)。
根据我的测试,这是我的测试应用程序,它的行为符合您的预期。
var cancelled = new ManualResetEvent(false);
Console.CancelKeyPress += (s, e) =>
{
e.Cancel = true;
Console.WriteLine("Ctrl+C detected...");
cancelled.Set();
};
Console.WriteLine("Running. The only thing to do now is ctrl+c or close the window...");
WaitHandle.WaitAny(new[] { cancelled });
Console.WriteLine("Press enter to exit...");
Console.ReadLine();