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



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

有没有办法创建一个"重试方法",使我每次这样做时都不会复制代码?

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

//  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() + "rn");
}, 10, 100);

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

我肯定希望看到处理这种特定模式(重试)的更好方法。

编辑:我在另一个答案中看着加利奥,这真的很棒。 请看这个例子:

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。 所以我想我的例子对你还是有用的。

我已经根据特定的域要求创建了这样的帮助程序,但作为一个通用的起点,请查看 Gallio 的实现。

http://www.gallio.org/api/html/T_MbUnit_Framework_Retry.htm

https://code.google.com/p/mb-unit/source/browse/trunk/v3/src/MbUnit/MbUnit/Framework/Retry.cs

http://interfacingreality.blogspot.co.uk/2009/05/retryuntil-in-mbunit-v3.html

最新更新