65.9K
CodeProject 正在变化。 阅读更多。
Home

用于重试管理的类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (4投票s)

2008年11月2日

CPOL

2分钟阅读

viewsIcon

39497

downloadIcon

297

允许开发者使用内置的重试机制,而无需自行开发。

ClassDiagram.jpg

引言

在许多情况下,开发者需要执行重试操作。例如,当应用程序尝试访问数据库读取数据,或从文件读取数据时。我们需要应用程序能够根据我们自己的参数进行重试,直到成功或我们希望它停止为止。

Using the Code

该库是一个DLL,可以在任何应用程序中使用。它允许指定重试计划。例如

  1. 重试20次,每隔5秒
  2. 重试30次,每隔1分钟
  3. 无限次重试,每隔1小时

这样的重试计划将使应用程序能够重试直到成功。以这种方式构建计划允许开发者确保网络/CPU不会因长时间的重试而过载。可以指定多个计划。每次前一个计划完成时,都会执行下一个计划。

重试管理器接受一个委托指向一个方法(感谢 Ramon 的提示)。该委托将调用调用应用程序中的一个函数。如果该委托返回 false 或抛出异常,重试管理器将根据定义的计划进行重试。

每次重试操作还会向调用应用程序引发一个事件,其中包含重试数据。这允许开发者记录重试事件、通知用户并管理它们。

随附的控制台应用程序尝试使用两个重试计划执行一项活动。如所示,它首先会尝试执行某项操作。失败后,它将每秒重试三次。如果失败,它将每2秒重试一次,无限期地进行。

TestConsole.jpg
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日 - 进行了一些更改和更新 - 尤其是使用委托
用于重试管理的类 - CodeProject - 代码之家
© . All rights reserved.