Search code examples
c#.netwaithandle

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. 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?


Solution

  • You need to cancel the CTRL+C command or else your process will be terminated:

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

    From 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.