如何为方法设置超时

Sur*_*esh 15 c# methods timeout

如何为busy方法+ C#设置超时.

Moj*_*ter 12

好的,这是真正的答案.

...

void LongRunningMethod(object monitorSync)
{
   //do stuff    
   lock (monitorSync) {
     Monitor.Pulse(monitorSync);
   }
}

void ImpatientMethod() {
  Action<object> longMethod = LongRunningMethod;
  object monitorSync = new object();
  bool timedOut;
  lock (monitorSync) {
    longMethod.BeginInvoke(monitorSync, null, null);
    timedOut = !Monitor.Wait(monitorSync, TimeSpan.FromSeconds(30)); // waiting 30 secs
  }
  if (timedOut) {
    // it timed out.
  }
}

   ...
Run Code Online (Sandbox Code Playgroud)

这结合了使用C#的两个最有趣的部分.首先,要异步调用该方法,请使用具有fancy-pants BeginInvoke魔法的委托.

然后,使用监视器从LongRunningMethod后面发送消息ImpatientMethod,让它知道它何时完成,或者如果它在一定时间内没有收到消息,就放弃它.

(ps-开玩笑说这才是真正的答案.我知道有2 ^ 9303种皮肤猫的方法.特别是在.Net)

  • 它确实有效,但是!请注意! - 当执行流程返回时,"LongRunningMethod"仍然在后台运行!这可能是泄漏. (4认同)
  • 如今,我更喜欢Task.Wait,但这对于使用"os primitives"和使用技术术语"fancy-pants"来说是很好的. (2认同)

ang*_*son 7

除非您更改方法,否则不能这样做.

有两种方法:

  1. 该方法以这样一种方式构建,即它本身测量它已经运行了多长时间,然后如果它超过某个阈值则过早地返回.
  2. 该方法的构建方式是监视一个变量/事件,该变量/事件显示"当设置此变量时,请退出",然后您有另一个线程测量在第一个方法中花费的时间,然后在经过的时间已超过某个门槛.

你可以得到的最明显,但不幸错误的答案是"只需在线程中运行该方法,并在运行时间过长时使用Thread.Abort".

唯一正确的方法是该方法以这样一种方式进行协作,即当它运行太长时它将执行干净的退出.

还有第三种方法,你在一个单独的线程上执行该方法,但在等待它完成之后,这需要很长时间才能完成,你只需说"我不会等待它完成,但只是丢弃它".在这种情况下,该方法仍将运行,并最终完成,但等待它的其他线程将放弃.

想想第三种方式是打电话给某人并要求他们在房子里搜索你借给他们的那本书,然后等到你手机结束5分钟后,你只需说"哇,扔掉它",然后挂断电话.最终,其他人会找到这本书并重新打电话,只是注意到你不再关心结果.


Sam*_*bes 5

This is an old question but it has a simpler solution now that was not available then: Tasks!

Here is a sample code:

var task = Task.Run(() => LongRunningMethod());//you can pass parameters to the method as well
if (task.Wait(TimeSpan.FromSeconds(30)))
    return task.Result; //the method returns elegantly
else
    throw new TimeoutException();//the method timed-out
Run Code Online (Sandbox Code Playgroud)