很好,干净的方式来重试几次

时间:2012-06-25 13:34:20

标签: c# .net exception

我经常遇到一些情况,如果他们失败,我必须重试一些操作,在一定次数后放弃,并在尝试之间短暂休息。

有没有办法创建'重试方法',这样我每次都不会复制代码?

2 个答案:

答案 0 :(得分:3)

厌倦了一遍又一遍地复制/粘贴相同的代码,所以我创建了一个方法来接受必须完成的任务的委托。这是:

//  logger declaration (I use NLog)
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
delegate void WhatTodo();
static void TrySeveralTimes(WhatTodo Task, int Retries, int RetryDelay)
{
    int retries = 0;
    while (true)
    {
        try
        {
            Task();
            break;
        }
        catch (Exception ex)
        {
            retries++;
            Log.Info<string, int>("Problem doing it {0}, try {1}", ex.Message, retries);
            if (retries > Retries)
            {
                Log.Info("Giving up...");
                throw;
            }
            Thread.Sleep(RetryDelay);
        }
    }
}

要使用它,我只想写:

TrySeveralTimes(() =>
{
    string destinationVpr = Path.Combine(outdir, "durations.vpr");
    File.AppendAllText(destinationVpr, file + ",     " + lengthInMiliseconds.ToString() + "\r\n");
}, 10, 100);

在这个例子中,我附加了一个被一些外部进程锁定的文件,只有写入它的方法是重试几次,直到进程完成...

我很乐意看到更好的方法来处理这种特殊模式(重试)。

编辑:我在另一个答案中看了Gallio,这真的很棒。看看这个例子:

Retry.Repeat(10) // Retries maximum 10 times the evaluation of the condition.
         .WithPolling(TimeSpan.FromSeconds(1)) // Waits approximatively for 1 second between each evaluation of the condition.
         .WithTimeout(TimeSpan.FromSeconds(30)) // Sets a timeout of 30 seconds.
         .DoBetween(() => { /* DoSomethingBetweenEachCall */ })
         .Until(() => { return EvaluateSomeCondition(); });

它做了一切。它甚至会在你编码的时候看着你的孩子:)但是,我力求简单,并且仍在使用.NET 2.0。所以我想我的例子仍然对你有用。

答案 1 :(得分:1)