【问题标题】:timing out a method call [duplicate]超时方法调用[重复]
【发布时间】:2013-09-01 07:38:39
【问题描述】:

原来的方法调用是这样的:

public string AskAPI(string uri)
{
    return api.Query(uri);
}

其中 api 只是一个导入的 dll 引用。

现在我想为 AskAPI 方法添加超时功能,这样如果 api.Query 花费的时间超过 30 秒,AskAPI 就会抛出异常。

似乎我无法让它工作。任何人都可以分享他们对此的想法吗?

谢谢!

【问题讨论】:

  • 您必须能够修改 api.Query 才能添加超时功能。由于您没有提供有关它是什么的信息,因此无法告诉您如何操作。 (没有办法让通话超时,因为根据您在此处发布的内容,您无法中断通话。)
  • @KenWhite api.Query 也不在我的控制范围内。你的意思是不编辑它,我不能让 AskAPI 方法超时?
  • 我无法回答这个问题,因为您提供了完全断章取义的三行代码({} 不算在内),完全没有其他信息。根据您发布的确切内容,答案将是“不,您不能”。

标签: c# multithreading


【解决方案1】:

您可以使用Tasks 来执行此操作,这是一个示例:

public string AskAPI(string uri, int millis)
{
    using (var task = new Task<string>(() => api.Query(uri)))
    {
        task.Start();
        task.Wait(millis);
        if (!task.IsCompleted) throw new TimeoutException();
        return task.Result;
    }   
}

感谢 Guillaume 建议使用 TimeoutException。

但正如 Jim Mischel 指出的那样,这不会阻止任务完成,在这种情况下,最好修改您正在调用的 API,因为这样您就可以充分利用 CancellationToken 类就是为这种事情而生的。

除此之外,我能想到的唯一其他快速解决方案(可能是不可取的)是将方法包装(或将其组合)如下:

public T Await<T>(Func<T> fun, int millis)
{
    using (var cancel = new CancellationTokenSource(millis))
    using (var task = new Task<T>(() =>
    {
        T result = default(T);
        var thread = new Thread(() => result = fun());
        thread.Start();
        while (!cancel.Token.IsCancellationRequested && thread.IsAlive) ; // Wait for a sign from above
        thread.Abort();
        cancel.Token.ThrowIfCancellationRequested();
        return result;
    }, cancel.Token))
    {
        task.Start();
        task.Wait(millis);
        cancel.Cancel();
        if (!task.IsCompleted) throw new TimeoutException();
        return task.Result;
    }
}

然后调用它:

Await(() => AskAPI("http://some.uri"), 30000);

【讨论】:

  • 不要扔Exception。投掷TimeoutException
  • @Guillaume 谢谢你,我应该花时间查一下。 =)
  • 但是任务继续执行,对吧?也就是说,api.Query 没有中止?
  • 看来这是解决我的问题的最佳实用方法
猜你喜欢
  • 2018-01-22
  • 2014-02-27
  • 2010-10-18
  • 2012-11-25
  • 1970-01-01
  • 1970-01-01
  • 2011-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多