简体   繁体   English

为什么这个短程序永远不会完成?

[英]Why does this short program never complete?

Through debugging a problem of my own, I have managed to recreate a tiny program which behaves very unusually: 通过调试我自己的问题,我设法重新创建了一个非常不寻常的小程序:

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

I would expect this program to: 我希望这个程序能够:

  • display the first line 显示第一行
  • wait until the user tries to exit the program 等到用户尝试退出程序
  • display the second line 显示第二行
  • wait until the user presses enter 等到用户按下回车键
  • exit 出口

However, once this makes it past the call to WaitHandle.WaitAny , it seems to hang on random lines. 但是,一旦这使它通过对WaitHandle.WaitAny ,它似乎挂在随机行上。 Sometimes the last line will never be printed, sometimes it will be printed but the enter key is never read. 有时最后一行永远不会被打印出来,有时它会被打印,但是输入键永远不会被读取。 With a larger code base, it can execute more lines of code and still hang at a seemingly random position. 使用更大的代码库,它可以执行更多代码行,并且仍然挂在看似随机的位置。

Can anyone explain this strange behaviour? 谁能解释这种奇怪的行为?

You need to cancel the CTRL+C command or else your process will be terminated: 您需要取消CTRL+C命令,否则您的进程将被终止:

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

From https://msdn.microsoft.com/en-us/library/system.consolecanceleventargs(v=vs.110).aspx : 来自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; 如果在事件处理程序中将Cancel属性设置为true,则恢复该进程; otherwise, the process is terminated. 否则,该过程终止。 By default, the value of the ConsoleCancelEventArgs property is false, and the process terminates. 默认情况下,ConsoleCancelEventArgs属性的值为false,并且该进程终止。

Ctrl + C is global command to close the command window. Ctrl + C是关闭命令窗口的全局命令。 So, This key combination will close the window before the actual program ends. 因此,此组合键将在实际程序结束之前关闭窗口。 Try using other key. 尝试使用其他密钥。

Please run the application without the debugger (directly from the command line). 请在没有调试器的情况下运行应用程序(直接从命令行)。

Here's my test app that behaves as you expect, according to my test. 根据我的测试,这是我的测试应用程序,其行为与您期望的一样。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM