用于重试管理的类






4.75/5 (4投票s)
允许开发者使用内置的重试机制,而无需自行开发。

引言
在许多情况下,开发者需要执行重试操作。例如,当应用程序尝试访问数据库读取数据,或从文件读取数据时。我们需要应用程序能够根据我们自己的参数进行重试,直到成功或我们希望它停止为止。
Using the Code
该库是一个DLL,可以在任何应用程序中使用。它允许指定重试计划。例如
- 重试20次,每隔5秒
- 重试30次,每隔1分钟
- 无限次重试,每隔1小时
这样的重试计划将使应用程序能够重试直到成功。以这种方式构建计划允许开发者确保网络/CPU不会因长时间的重试而过载。可以指定多个计划。每次前一个计划完成时,都会执行下一个计划。
重试管理器接受一个委托指向一个方法(感谢 Ramon 的提示)。该委托将调用调用应用程序中的一个函数。如果该委托返回 false
或抛出异常,重试管理器将根据定义的计划进行重试。
每次重试操作还会向调用应用程序引发一个事件,其中包含重试数据。这允许开发者记录重试事件、通知用户并管理它们。
随附的控制台应用程序尝试使用两个重试计划执行一项活动。如所示,它首先会尝试执行某项操作。失败后,它将每秒重试三次。如果失败,它将每2秒重试一次,无限期地进行。

static RetryTimer.RetryManager manager = new RetryTimer.RetryManager();
static void Main(string[] args)
{
Console.WriteLine("Trying...");
if (!TrySomething())
{
Console.WriteLine("Failed, Retrying");
//The action we tried did not succeed
//Add an event handler to the retry mechanism
manager.DoRetry += new RetryTimer.RetryHandler(manager_DoRetry);
//add 2 schedules
//Try 5 times every 1 second
manager.AddSchedule(RetryTimer.MeasurementUnit.Seconds, 3, 1);
//If still unsuccessful - try indefinitely every 10 seconds
manager.AddSchedule(RetryTimer.MeasurementUnit.Seconds, -1, 2);
//Start Retry
RetryTimer.RetryCallback handler = TrySomething;
manager.Start(handler);
Console.ReadLine();
}
else
{
//The actions succeeded
Console.WriteLine("Success!");
}
}
重试事件处理程序处理重试并向重试管理器报告重试结果。
static void manager_DoRetry(object sender, RetryTimer.DoRetryEventArgs args)
{
Result = (string.Format("Retrying {0} of {1} every {2} {3} at {4}",
new object[] {args.CurrentRetry,
args.CurrentSchedule.RetryCount,
args.CurrentSchedule.UnitCount,
args.CurrentSchedule.UnitOfMeasure.ToString(),
DateTime.Now.ToString()}));
Console.WriteLine(Result);
}
重试管理器将根据计划调用委托,直到停止或计划完成为止。
public void Start(RetryCallback callback)
{
StopRequested = false;
if (mScheduleList.Count == 0)
{
throw new Exception("No Schedules defined. Cannot Start");
}
bool successTry = false;
//loop through all schedules
while (currentScheduleIndex <= (mScheduleList.Count - 1) &&
!successTry && !StopRequested)
{
while ((ElapsedCount <= mScheduleList[currentScheduleIndex].RetryCount ||
mScheduleList[currentScheduleIndex].RetryCount<0) &&
!successTry && !StopRequested)
{
try
{
if (callback())
{
successTry = true; ;
}
}
catch (Exception ex)
{
//throw;
}
if (DoRetry != null)
{
DoRetry(this, new DoRetryEventArgs
(mScheduleList[currentScheduleIndex], ElapsedCount));
}
if (!successTry)
{
for (int numberOfUnits = 0;
numberOfUnits < mScheduleList
[currentScheduleIndex].UnitCount *
Convert.ToUInt32( mScheduleList
[currentScheduleIndex].UnitOfMeasure) / 1000;
numberOfUnits++)
{
System.Threading.Thread.Sleep(1000);
}
}
ElapsedCount++;
}
currentScheduleIndex++;
ElapsedCount = 1;
}
}
历史
- 2008年11月3日 - 文章的初始发布
- 2008年11月5日 - 进行了一些更改和更新 - 尤其是使用委托