这是好习惯吗?

时间:2016-03-11 11:42:08

标签: c# exception-handling

我有这个扩展方法,允许我在有异常的情况下重试操作,典型的用法是尝试写入文件,但由于某种原因我不能这样,我稍后再试... < / p>

扩展名如下:

public static void WithRetry<T>(this Action action, int timeToWait = 500, int timesToRetry = 3) where T : Exception
{
    int retryCount = 0;

    bool successful = false;

    do
    {
        try
        {
            action();
            successful = true;
        }
        catch (T)
        {
            retryCount++;
            Thread.Sleep(timeToWait);
            if (retryCount == timesToRetry) throw;
        }
        catch (Exception)
        {
            throw;
        }
    } while (retryCount < timesToRetry && !successful);
}

Visual Studio告诉我,我在第一个捕获块中吞下了异常,这是不是很糟糕?

感谢。

2 个答案:

答案 0 :(得分:2)

警告正是您要实现的目标。您正在吞咽异常(timesToRetry-1)次。在最后一次尝试中,您实际上只是抛出异常。在此之前,所有异常都将被吞噬和丢失。因为这是你想要实现的行为。压制消息没有害处。

但正如@HimBromBeere所说,删除catch(Exception)块。此外,您可以尝试在每次重试时记录异常,因为您将丢失此数据。如果每次抛出不同类型的异常怎么办?没有办法确定。

答案 1 :(得分:2)

警告是正确的,你吞下异常。如果你重试10次,你将永远不知道前9次出了什么问题,你只能获得10号异常。

也许这就是你想要的。就个人而言,我会将所有发生的异常放入AggregateException并在您重试计数时抛出

也许是这样的:

    public static void WithRetry<T>(this Action action, int timeToWait = 500, int timesToRetry = 3) where T : Exception
    {
        var exceptions = new List<Exception>();

        for (int tryIndex = 0; tryIndex < timesToRetry; tryIndex++)
        {
            try
            {
                action();

                return;
            }
            catch (T t)
            {
                exceptions.Add(t);
            }

            Thread.Sleep(timeToWait);
        }

        throw new AggregateException(exceptions);
    }