为了账号安全,请及时绑定邮箱和手机立即绑定

实现C#通用超时

实现C#通用超时

C#
湖上湖 2019-07-04 12:44:32
实现C#通用超时我正在寻找好的想法来实现一种通用的方法,让一行代码(或匿名委托)以超时形式执行。TemperamentalClass tc = new TemperamentalClass();tc.DoSomething();  // normally runs in 30 sec.  Want to error at 1 min我正在寻找一种解决方案,它可以在我的代码与变化无常的代码交互的许多地方优雅地实现(这是我无法更改的)。此外,如果可能的话,我想让冒犯的“超时”代码停止执行。
查看完整描述

3 回答

?
慕少森

TA贡献2019条经验 获得超9个赞

嗯,您可以使用委托(BeginInvoke,回调设置一个标志-以及等待该标志或超时的原始代码)来完成任务,但问题是很难关闭正在运行的代码。例如,杀死(或暂停)线程是危险的.所以我不认为有一个容易的方法来做这件事。

我会发布这篇文章,但请注意,这并不理想-它不会停止长期运行的任务,并且在失败时也不会进行适当的清理。

    static void Main()
    {
        DoWork(OK, 5000);
        DoWork(Nasty, 5000);
    }
    static void OK()
    {
        Thread.Sleep(1000);
    }
    static void Nasty()
    {
        Thread.Sleep(10000);
    }
    static void DoWork(Action action, int timeout)
    {
        ManualResetEvent evt = new ManualResetEvent(false);
        AsyncCallback cb = delegate {evt.Set();};
        IAsyncResult result = action.BeginInvoke(cb, null);
        if (evt.WaitOne(timeout))
        {
            action.EndInvoke(result);
        }
        else
        {
            throw new TimeoutException();
        }
    }
    static T DoWork<T>(Func<T> func, int timeout)
    {
        ManualResetEvent evt = new ManualResetEvent(false);
        AsyncCallback cb = delegate { evt.Set(); };
        IAsyncResult result = func.BeginInvoke(cb, null);
        if (evt.WaitOne(timeout))
        {
            return func.EndInvoke(result);
        }
        else
        {
            throw new TimeoutException();
        }
    }


查看完整回答
反对 回复 2019-07-04
  • 3 回答
  • 0 关注
  • 1082 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信