有没有立即触发WaitOne()超时的方法?

时间:2014-03-27 04:38:49

标签: c# .net windows multithreading

在Microsoft .NET中,方法WaitOne()

public virtual bool WaitOne(
TimeSpan timeout
)
如果当前实例收到信号,

将返回true;否则,false

我的问题是,即使超时点尚未到来,有没有办法让它返回false

换句话说,即使没有真正的超时点,有没有办法在WaitOne()上立即触发超时?

更新

该项目基于 .NET 3.5 ,因此ManualResetEventSlim可能不起作用(在.NET 4中引入)。无论如何,谢谢 @ani

3 个答案:

答案 0 :(得分:6)

您无法取消WaitOne,但可以将其打包:

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;
}

只需传递您想要等待的句柄,然后使用句柄取消等待和超时。

<强>附加

作为一种扩展方法,可以通过与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;
}

答案 1 :(得分:5)

您似乎希望等待一段时间的信号,同时还能够在正在进行的过程中取消等待操作。

实现此目的的一种方法是使用ManualResetEventSlim方法将Wait(TimeSpan timeout, CancellationToken cancellationToken)与取消令牌一起使用。在这种情况下,将发生以下三种情况之一:

  1. 一旦事件发出信号(在超时完成之前),Wait操作将立即为true。
  2. 如果事件未在超时点发出信号,则Wait操作将以false结束。
  3. 如果在等待操作正在进行时设置了取消令牌,则会抛出OperationCanceledException。

答案 2 :(得分:0)

如果您set发出信号,它将释放等待线程;