Yuanhang Guo
Yuanhang Guo

Reputation: 486

Any way to trigger timeout on WaitOne() immediately?

In Microsoft .NET, the method WaitOne()

public virtual bool WaitOne(
TimeSpan timeout
)

will return true if the current instance receives a signal; otherwise, false.

My question is, is there a way to let it return false even if the timeout point has not came yet?
Or
In another words, is there a way to immediately trigger a timeout on WaitOne() even if the real timeout point has not came?

Update:

The project is based on .NET 3.5, so the ManualResetEventSlim may not work (introduced in .NET 4). Thanks @ani anyway.

Upvotes: 6

Views: 5659

Answers (3)

Emond
Emond

Reputation: 50672

You can't cancel the WaitOne but you could wrap it:

public bool Wait(WaitHandle yourEvent, WaitHandle cancelEvent, TimeSpan timeOut)
{
   WaitHandle[] handles = new WaitHandle[] { yourEvent, cancelEvent };

   // WaitAny returns the index of the event that got the signal
   var waitResult = WaitHandle.WaitAny(handles, timeOut);  

   if(waitResult == 1)
   {
       return false; // cancel!
   }

   if(waitResult == WaitHandle.WaitTimeout)
   {
       return false; // timeout
   }

   return true;
}

Just pass the handle you want to wait for and a handle to cancel the waiting and a time out.

Extra

As an extension method so it can be called in a similar way to the WaitOne:

public static bool Wait(this WaitHandle yourEvent, WaitHandle cancelEvent, TimeSpan timeOut)
{
   WaitHandle[] handles = new WaitHandle[] { yourEvent, cancelEvent };

   // WaitAny returns the index of the event that got the signal
   var waitResult = WaitHandle.WaitAny(handles, timeOut);  

   if(waitResult == 1)
   {
       return false; // cancel!
   }

   if(waitResult == WaitHandle.WaitTimeout)
   {
       return false; // timeout
   }

   return true;
}

Upvotes: 8

Ani
Ani

Reputation: 113412

It appears you want to wait for a signal for a certain amount of time, while also being able to cancel the wait operation while it is in progress.

One way to achieve this is to use a ManualResetEventSlim together with a cancellation token using the Wait(TimeSpan timeout, CancellationToken cancellationToken) method. In this case, one of three things will happen:

  1. The Wait operation will complete with true as soon as the event is signaled (before the timeout completes).
  2. The Wait operation will complete with false if the event hasn't been signaled at the timeout point.
  3. An OperationCanceledException will be thrown if the cancellation-token is set while the wait operation is in progress.

Upvotes: 6

rerun
rerun

Reputation: 25505

If you set the event to signaled it will free the waiting thread;

Upvotes: 1

Related Questions