通用尝试并在C#中使用超时重试?

Mik*_*ike 5 .net c#

我正在寻找一个通用的尝试,并在C#中使用超时重试.基本上,我想要以下内容:

bool stopTrying = false;
DateTime time = DateTime.Now;
while (!stopTrying)
{
    try
    {
        //[Statement to Execute]
    }
    catch (Exception ex)
    {
        if (DateTime.Now.Subtract(time).Milliseconds > 10000)
        {
            stopTrying = true;
            throw ex;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我等待10秒,但它应该是基于参数的变量超时.我不想在需要使用它的任何地方重复这个完整的代码.我的代码中有多个地方,它们不是API中内置的超时,如果应用程序尚未准备好执行语句,我将遇到异常.这也可以避免在这些声明之前对我的应用程序中的延迟进行硬编码.

澄清:有关陈述可能类似于转让.如果我使用委托和method.Invoke,是不是作用在委托内的调用而不是原始方法?

str*_*ger 15

使用您的示例,解决方案很简单:

bool DoOrTimeout<T>(T method, TimeSpan timeout) where T : delegate // FIXME
{
    bool stopTrying = false;
    DateTime time = DateTime.Now;
    while (!stopTrying)
    {
        try
        {
            method.Invoke();
            stopTrying = true;
        }
        catch (Exception ex)
        {
            if (DateTime.Now.Subtract(time).Milliseconds > timeout.TotalMilliseconds)
            {
                stopTrying = true;
                throw;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

只需DoOrTimeout使用委托作为第一个参数调用.

  • 请使用`throw;`来重新抛出异常,而不是`throw ex;`,因为后者会破坏堆栈跟踪. (8认同)
  • 这段代码无法编译。delegate 不能用作约束。 (2认同)
  • 将一个“TimeSpan”上的“毫秒”与另一个“TimeSpan”上的“TotalMilliseconds”进行比较一定是一个拼写错误(错误)。为什么不直接比较 `TimeSpan` 呢?该类型会重载通常的运算符。因此: `if (DateTime.Now - time &gt; timeout) { ... }` 更正确。 (2认同)