Search code examples
c#multithreadingautoreseteventevent-wait-handle

Proper Way to Stop App While Threads Are Waiting on WaitOne()


I'm playing around with AutoResetEvent and my app isn't ending, and I think I know why: the threads are still running and therefore the app won't terminate. Normally, in Main(), after I press a key, the app terminates. But the console window no longer closes. I have a simple console app:

    private static EventWaitHandle waitHandle = new AutoResetEvent(false);

    static void Main(string[] args)
    {
        AutoResetEventFun();

        Console.WriteLine("Press any key to end.");
        Console.ReadKey();

        waitHandle.Close();  // This didn't cause the app to terminate.
        waitHandle.Dispose();  // Nor did this.
    }

    private static void AutoResetEventFun()
    {
        // Start all of our threads.
        new Thread(ThreadMethod1).Start();
        new Thread(ThreadMethod2).Start();
        new Thread(ThreadMethod3).Start();
        new Thread(ThreadMethod4).Start();

        while (Console.ReadKey().Key != ConsoleKey.X)
        {
            waitHandle.Set();  // Let one of our threads process.
        }
    }

    // There are four of these methods. Only showing this one for brevity.
    private static void ThreadMethod1()
    {
        Console.WriteLine("ThreadMethod1() waiting...");

        while (true)
        {
            waitHandle.WaitOne();
            Console.WriteLine("ThreadMethod1() continuing...");   
        }
    }

What's the right way to terminate this app? Do I need to retain a reference to each thread and call Abort() on each one? Is there a way to signal waitHandle so that the threads waiting on it will terminate? (I don't think so, but I thought it would be worth asking.)


Solution

  • While I'm not entirely sure what you're trying to accomplish, one way to have this app terminate is to make all thread background threads:

    private static void ThreadMethod1()
    { 
        Thread.CurrentThread.IsBackground = true;
        Console.WriteLine("ThreadMethod1() waiting...");
    
        while (true)
        {
            waitHandle.WaitOne();
            Console.WriteLine("ThreadMethod1() continuing...");   
        }
    }