C# 为什么这个简短的计划永远都没有完成?

C# 为什么这个简短的计划永远都没有完成?,c#,.net,waithandle,C#,.net,Waithandle,通过调试我自己的一个问题,我成功地重新创建了一个行为异常的小程序: using System; using System.Threading; namespace CancelBug { class Program { static void Main(string[] args) { var unused = new ManualResetEvent(false); var cancelled =

通过调试我自己的一个问题,我成功地重新创建了一个行为异常的小程序:

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();
        }
    }
}
我希望该计划能够:

  • 显示第一行
  • 等待用户尝试退出程序
  • 显示第二行
  • 等待用户按enter键
  • 出口
然而,一旦它通过了对
WaitHandle.WaitAny
的调用,它就好像挂起了随机线。有时最后一行永远不会打印,有时会打印,但不会读取回车键。有了更大的代码库,它可以执行更多的代码行,并且仍然挂起在一个看似随机的位置


有人能解释这种奇怪的行为吗?

Ctrl+C
是关闭命令窗口的全局命令。因此,此组合键将在实际程序结束前关闭窗口。尝试使用其他键。

您需要取消
CTRL+C
命令,否则您的进程将终止:

Console.CancelKeyPress += (s, e) =>
{
    e.Cancel = true;
    cancelled.Set();
};
发件人:

如果在事件处理程序中将Cancel属性设置为true,则 过程恢复;否则,进程将终止。默认情况下, ConsoleCancelEventArgs属性的值为false,并且 进程终止


请在不使用调试器的情况下运行应用程序(直接从命令行)

根据我的测试,这是我的测试应用程序,它的性能和你期望的一样

        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();

在我看来,它可能是调试器。我在调试器之外运行了这个程序,每次它都会强制退出,而不打印更多的行。我认为Fregger的回答解释了为什么强制退出是预期行为(谁知道你必须取消取消)。我想进程没有终止,因为调试器已附加。如果不想继续退出,答案是正确的。如果要收听
Ctrl+C
,则不取消该事件。如果你想避免用户这样做,你也可以在控制台上禁用
Ctrl+C
特殊组合键。哦,天哪,真的这么简单吗?我在这上面花了几个小时。。。我将在明天早上尝试这一点,并让您知道,我发现在使用
取消.WaitOne()
时不会发生这种情况,但在使用
WaitHandle.WaitAny()时确实会发生这种情况。您已经解决了这个问题(谢谢),但尚未解释您所做的代码更改。我认为弗雷格的回答值得称赞