0

Exactly when does WaitHandle WaitOne(int timeout) return? Does it return when the timeout has elapsed? I see some code online which suggests polling WaitOne() when implementing logic which does some cleanup before exiting. This implies that WaitOne() does not return when the timeout elapses; instead it returns whether or not it is signaled immediately after it is called.

public void SomeMethod()
{
  while (!yourEvent.WaitOne(POLLING_INTERVAL))
  {
    if (IsShutdownRequested())
    {
      // Add code to end gracefully here.
    }
  }
  // Your event was signaled so now we can proceed.
}

What I am trying to achieve here is a way to signal the WaitHandle using a CancellationToken while it is blocking the calling thread.

TheWolf
  • 1,675
  • 4
  • 22
  • 34
  • 2
    [Did you read the manual?](https://msdn.microsoft.com/en-us/library/cc189907(v=vs.110).aspx) –  Oct 06 '15 at 01:02
  • Hopefully it returns when the event gets signaled within a reasonable time. If it doesn't then you have two problems. Having no idea what to put inside that if() statement is pretty normal. We don't know what "graceful" might mean either when something pretty ungraceful happened. Throwing an exception is usually about as graceful as it gets. Just don't use a timeout if you don't know what to do about it, at least you can debug that. – Hans Passant Oct 06 '15 at 01:04
  • Ok thanks. I understand that it returns immediately after it is signaled. So in the case it does not get signaled within the timeout period it will return false and not return any exceptions? In this case polling WaitOne does not make sense. I want to essentially stop blocking the calling thread while it is waiting even before the WaitHandle times out or is signaled. Any suggestions? – TheWolf Oct 06 '15 at 01:12

1 Answers1

1

"I want to essentially stop blocking the calling thread while it is waiting even before the WaitHandle times out or is signaled" -- under what condition would you want the thread to become unblocked? Do you already have a CancellationToken object you're using?

If so, then you could do something like this:

public void SomeMethod(CancellationToken token)
{
  int waitResult;

  while ((waitResult = WaitHandle.WaitAny(
      new [] { yourEvent, token.WaitHandle }, POLLING_INTERVAL)) == WaitHandle.WaitTimeout)
  {
    if (IsShutdownRequested())
    {
      // Add code to end gracefully here.
    }
  }
  if (waitResult == 0)
  {
      // Your event was signaled so now we can proceed.
  }
  else if (waitResult == 1)
  {
      // The wait was cancelled via the token
  }
}

Note that the use of WaitHandle is not necessarily ideal. .NET has modern, managed thread synchronization mechanisms that work more efficiently than WaitHandle (which is based on native OS objects that incur greater overhead). But if you must use WaitHandle to start with, the above is probably an appropriate way to extend your current implementation to work with CancellationToken.

If the above does not address your question, please improve the question by providing a good, minimal, complete code example that clearly illustrates the scenario, along with a detailed explanation of what that code example does now and how that's different from what you want it to do.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136