如何设置一个超时对一个繁忙的方法+C#。

有帮助吗?

解决方案

好的,这是真正的答案。

...

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

   ...

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

然后,使用监视器将 LongRunningMethod 中的消息发送回 ImpatientMethod ,让它知道什么时候完成,或者它是否没有收到消息在一定的时间内,放弃它。

(p.s.-开玩笑说这才是真正的答案。我知道有2 ^ 9303种皮肤猫的方法。尤其是.Net)

其他提示

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

有两种方法:

  1. 该方法的构建方式是它本身可以测量运行的时间,然后在超过某个阈值时提前返回。
  2. 该方法的构建方式是监视一个变量/事件,该变量/事件显示“当设置此变量时,请退出”,然后您有另一个线程测量在第一个方法中花费的时间,然后设置当经过的时间超过某个阈值时,该变量。
  3. 最明显的,但不幸的是错误的答案,你可以在这里得到的是“只需在线程中运行该方法,并在运行太长时间时使用Thread.Abort”。

    唯一正确的方法是让方法以这样一种方式进行合作:当它运行的时间过长时,它会进行干净的退出。

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

    想想第三种方式,就是打电话给别人并要求他们在房子里搜索你借给他们的那本书,然后在等待电话结束5分钟之后,你只需说“aw,chuck it”,然后挂断。最终,其他人会找到这本书并重新打电话,只是注意到你不再关心结果。

MojoFilter的答案很不错如果使用“LongMethod”,它会导致泄漏。冻结。如果你对结果不感兴趣,你应该中止操作。

public void LongMethod()
{
    //do stuff
}

public void ImpatientMethod()
{
    Action longMethod = LongMethod; //use Func if you need a return value

    ManualResetEvent mre = new ManualResetEvent(false);

    Thread actionThread = new Thread(new ThreadStart(() =>
    {
        var iar = longMethod.BeginInvoke(null, null);
        longMethod.EndInvoke(iar); //always call endinvoke
        mre.Set();
    }));

    actionThread.Start();
    mre.WaitOne(30000); // waiting 30 secs (or less)
    if (actionThread.IsAlive) actionThread.Abort();
}

这是一个古老的问题,但它现在有一个更简单的解决方案,现在还没有:任务!

以下是示例代码:

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

方法在C#中没有超时,除非您在调试器或操作系统中认为您的应用已“挂起”。即使这样,处理仍然继续,只要您不杀死应用程序,就会返回响应并且应用程序继续工作。

调用数据库可能会超时。

您是否可以创建异步方法,以便继续其他东西,而“繁忙”的东西方法完成了?

我定期编写的应用程序,我要同步时间的关键任务的平台。如果你可以避免的线。中止你应该。看看 http://blogs.msdn.com/b/ericlippert/archive/2010/02/22/should-i-specify-a-timeout.aspxhttp://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation 对于准则的时候螺纹。中止是适当的。这里的概念,我实现:

  • 选择性的执行:只有运行,如果有合理的成功机会的存在(根据能力,以满足超时或成功的可能性的结果相对于其他排队的项目)。如果你把代码转段并且知道大致预期的时间之间任务组块,你可以预测,如果你要跳过的任何进一步处理。总的时间可通过包裹的对象站的任务用递归功能的时间计算,或者通过具有一个控制器类表工人知道预计等待时间。
  • 选择孤立:只有等待返回,如果合理的成功机会的存在。编制索引的任务是在运行一个管理队。任务超过他们的超时或风险造成的其他超时是孤立和零记录返回他们的帮助。再运行的任务可以包裹在异步通话。见例如异步呼包装: http://www.vbusers.com/codecsharp/codeget.asp?ThreadID=67&PostID=1
  • 有条件的选择:类似的选择性执行的,但根据组中而不是个别的任务。如果很多你的任务是相互连接,使得一个成功或失败使其他处理无关紧要,创建一个标志,检查在执行开始之前和之前再次运行时间长子的任务开始。这是特别有用的,当你用的是平行的。或者其他诸如排队并发的任务。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top