Search code examples
c#multithreadingidisposableshutdownwaithandle

How do you close an application when some WaitHandle is in the middle of a call to WaitOne?


Is there a standard way to close out an application "cleanly" while some WaitHandle objects may be in the state of a current blocking call to WaitOne?

For example, there may be a background thread that is spinning along in a method like this:

while (_request.WaitOne())
{
    try
    {
        _workItem.Invoke();
    }
    finally
    {
        OnWorkCompleted();
    }
}

I see no obvious way to dispose of this thread without calling Thread.Abort (which from what I understand is discouraged). Calling Close on the _request object (an AutoResetEvent), however, will throw an exception.

Currently, the thread that is running this loop has its IsBackground property set to true, and so the application appears to close properly. However, since WaitHandle implements IDisposable, I'm unsure if this is considered kosher or if that object really ought to be disposed before the app exits.

Is this a bad design? If not, how is this scenario typically dealt with?


Solution

  • Define an additional WaitHandle called _terminate that will signal a request to terminate the loop and then use WaitHandle.WaitAny instead of WaitHandle.WaitOne.

    var handles = { _request, _terminate };
    while (WaitHandle.WaitAny(handles) == 0)
    {
      try
      {
        _workItem.Invoke();
      }
      finally
      {
        OnCompleteWork();
      }
    }