Movatterモバイル変換


[0]ホーム

URL:


Wayback Machine
8 captures
08 Nov 2008 - 13 May 2009
JanMAYJun
Previous capture13Next capture
200820092010
success
fail
COLLECTED BY
Organization:Alexa Crawls
Starting in 1996,Alexa Internet has been donating their crawl data to the Internet Archive. Flowing in every day, these data are added to theWayback Machine after an embargo period.
Collection:alexa_web_2009
this data is currently not publicly accessible.
TIMESTAMPS
loading
The Wayback Machine - https://web.archive.org/web/20090513182743/http://www.codeproject.com:80/KB/miscctrl/retryManager.aspx
Click here to Skip to main content
6,148,461 members and growing! (15,586 online)
EmailPassword helpLost your password?
The Code Project
Desktop Development »Miscellaneous »General    IntermediateLicense:The Code Project Open License (CPOL)

A Class for Retry Management

ByRotem Sapir

Allows the developer to use a built-in retry machanism, instead of having to develop it.
C#, .NET, Dev
Posted:2 Nov 2008
Updated:6 Nov 2008
Views:6,166
Bookmarked:45 times
Announcements
CompSmart Client Comp
CompMonthly Competition
Loading...
Chapters
Desktop Development
Button Controls
Clipboard
Combo & List Boxes
Dialogs and Windows
Desktop Gadgets
Document / View
Edit Controls
Files and Folders
Grid & Data Controls
List Controls
Menus
Miscellaneous
Printing
Progress Controls
Selection Controls
Shell and IE programming
Smart Client
Splitter Windows
Static & Panel Controls
Status Bar
Tabs & Property Pages
Toolbars & Docking windows
Tree Controls
Web Development
Ajax and Atlas
Applications & Tools
ASP
ASP.NET
ASP.NET Controls
ATL Server
Caching
Charts, Graphs and Images
Client side scripting
Custom Controls
HTML / CSS
ISAPI
Site & Server Management
Session State
Silverlight
Trace and Logs
User Controls
Validation
View State
WAP / WML
Web Security
Web Services
Enterprise Systems
Content Management Server
Microsoft BizTalk Server
Microsoft Exchange
Office Development
SharePoint Server
Multimedia
Audio and Video
DirectX
GDI
GDI+
General Graphics
OpenGL
Database
Database
SQL Reporting Services
Platforms, Frameworks & Libraries
ATL
MFC
STL
WTL
COM / COM+
.NET Framework
Win32/64 SDK & OS
Vista API
Vista Security
Cross Platform
Game Development
Mobile Development
Windows CardSpace
Windows Communication Foundation
Windows Presentation Foundation
Windows Workflow Foundation
Libraries
Windows Powershell
LINQ
Languages
C / C++ Language
C++ / CLI
C#
MSIL
VBScript
VB.NET
VB6 Interop
Other .NET Languages
XML
Java
General Programming
Algorithms & Recipes
Bugs & Workarounds
Collections
Cryptography & Security
Date and Time
DLLs & Assemblies
Exception Handling
Localisation
Macros and Add-ins
Programming Tips
String handling
Internet / Network
Threads, Processes & IPC
WinHelp / HTMLHelp
Graphics / Design
Expression
Usability
Development Lifecycle
Debug Tips
Design and Architecture
Installation
Work Issues
Testing and QA
Code Generation
General Reading
Book Chapters
Book Reviews
Hardware Reviews
Interviews
Scrapbook
Hardware & System
Uncategorised Technical Blogs
Third Party Products
Product Showcase
Solution Center
Services
Product Catalog
Code-signing Certificates
Job Board
CodeProject VS2008 Addin
Feature Zones
Product Showcase
WhitePapers / Webcasts
ASP.NET Web Hosting
 
Search    
Advanced Search
printPrint  Broken Article?Report      addShare
 DiscussDiscuss  Recommend Article Email
4 votes for this article.
Popularity: 2.86Rating:4.75 out of 5

1

2

3
1 vote, 25.0%
4
3 votes, 75.0%
5
ClassDiagram.jpg

Introduction

On numerous occasions, it becomes necessary for a developer to perform retries. For example, when an application tries to access the DB to read data, or read from a file. We'll need our application to be able to retry, based on our own parameters, until it is successful, or until we want it to stop.

Using the Code

The library is a DLL which can be used in any application. It allows to specify a retry schedule. For example:

  1. Retry 20 times, every 5 seconds
  2. Retry 30 times, every minute
  3. Retry forever, every hour

Such a retry schedule will enable the application to retry until it succeeds. Building a schedule this way allows the developer to make sure that the network/CPU is not overloaded by retries for a long time. It is possible to specify multiple schedules. Each will follow the other when the previous one completes.

The retry manager accepts a delegate to a method (Thanks toRamon for the tip). This delegate will call a function in the calling application. If that delegate returnsfalse or throws an exception, the retry manager will retry based on the schedule defined.

Each retry action also raises an event to the calling application, with the retry data. This allows the developer to log the retry events, notify the user, and manage them.

The attached console application tries to perform an activity with two retry schedules. As shown, it will first try to do something. After failure, it will retry three times every second. If it fails, it will try every 2 seconds, indefinitely.

TestConsole.jpg
static RetryTimer.RetryManager manager =new RetryTimer.RetryManager();staticvoid 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!");            }}

The retry event handler handles retrying and reports the results of the retry to the retry manager.

staticvoid manager_DoRetry(object sender, RetryTimer.DoRetryEventArgs args){  Result = (string.Format("Retrying {0} of {1} every {2} {3} at {4}",newobject[] {args.CurrentRetry,                                          args.CurrentSchedule.RetryCount,                                          args.CurrentSchedule.UnitCount,                                          args.CurrentSchedule.UnitOfMeasure.ToString(),                                          DateTime.Now.ToString()}));    Console.WriteLine(Result);}

The retry manager will call the delegate based on the schedule, until stopped or until the schedules are completed.

publicvoid Start(RetryCallback callback)        {            StopRequested =false;if (mScheduleList.Count ==0)            {thrownew Exception("No Schedules defined. Cannot Start");            }bool successTry =false;//loop through all scheduleswhile (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;            }        }

History

  • 3rdNovember, 2008 - Initial release of the article
  • 5thNovember, 2008 - Some changes and updates - especially using a delegate

License

This article, along with any associated source code and files, is licensed underThe Code Project Open License (CPOL)

About the Author

Rotem Sapir


Member

Occupation:Web Developer
Location:Israel Israel

Other popular Miscellaneous articles:

Article Top
Sign Up to vote for this article
Your reason for this vote:
 Msgs 1 to 7 of 7 (Total in Forum: 7) (Refresh)FirstPrevNext
GeneralGood articlememberDonsw17:59 22 Jan '09  
I have a program in the near future that may need this, I will keep it in mind and use it then. thanks
General"Console.ReadLine();" in "manager_DoRetry(...)"memberNorbertKl172:51 5 Nov '08  
Nice, but I don't get the "Console.ReadLine();" in "manager_DoRetry(...)".
Won't you get a pile of manager_DoRetrys waiting for some action from the Console? I took it out, and it works just fine.
Regards
Norbert
GeneralRe: "Console.ReadLine();" in "manager_DoRetry(...)"memberRotem Sapir4:28 6 Nov '08  
Thanks,
I'm not sure why it's there.
GeneralRedundancy, reliability, etc.memberDmitri Nesteruk6:22 4 Nov '08  
In my experience, when reliability is concerned, there's never a solution that fits all. One example I can think of is ideas regarding how to handle repeats in locking scenarios. Say you've got aTimerLock and it times out - would you try again? Inform the calling thread? Ignore it? A general-purpose framework might be of some use in limited, single-threaded scenarios, but if there's one feature of reliability characteristics that's bound to rear its ugly head, it's the fact that operations separate into threads, AppDomains, and so on.
GeneralRe: Redundancy, reliability, etc.memberRotem Sapir4:27 6 Nov '08  
In this case, this class is designed mainly for single threaded scenarios.
This class will be used in windows services, which during startup try to get data from the database.
GeneralThe following helper class does this toomemberRamon Smits2:50 3 Nov '08  
I didn't take a look at your source code but I created the following helper class years ago. It allows you to easily add a retry mechanism to a statement:


Retry.Delegate statement = delegate { Console.WriteLine("Fire"); throw new Exception("Error"); };

Retry.Do<(
5, // Retry count
1000, // Minimum time for retry
5000, // Maximum time for retry
statement); // What code to retry

This can ofcourse be done in a combined statement but written this way to easily see how it works.

By the way... I seriously am against retry mechanisms in back-end code! Back-ends should never retry unless it is an automated process and even then you should be very carefull with such designs.


/// <summary>
/// Helper class to make it more easy to retry actions like for example webrequests.
/// </summary>
public static class Retry
{
private static readonly Random _randomSleep = new Random();

/// <summary>
/// Delegate to be used by implementation that need a retry mechanism.
/// </summary>
public delegate void Delegate();

/// <summary>
/// Perform an operation and when it fails (exception occurs) then retry it a couple of times with a configured delay in between.
/// </summary>
/// <typeparam name="T">The exception type that is allowed to occur.</typeparam>
/// <param name="count">Maximum retry count</param>
/// <param name="minWait">Minimum delay before a new attemp is made.</param>
/// <param name="maxWait">Maximum delay before a new attemp is made.</param>
/// <param name="method">Method to call.
/// <remarks>
/// The minimum and maximum wait arguments are there so that clients will not retry an operation all at the same time which could result in yet again unnecessary failure. This is especially usefull for retrying operations over the network especially in combination with <see cref="T"/> to specify <see cref="WebException"/>.
/// </remarks>
public static void Do<T>(
int count,
int minWait,
int maxWait,
Delegate method
) where T : Exception
{
start:
--count;
try
{
method();
}
catch (T)
{
if (count == 0)
{
throw;
}

if (maxWait > 0)
{
Thread.Sleep(_randomSleep.Next(minWait, maxWait));
}

goto start;
}
}

/// <summary>
/// Perform an operation and when it fails (exception occurs) then retry it a couple of times.
/// </summary>
/// <param name="count">Maximum retry count</param>
/// <param name="method">Method to call.</param>
public static void Do(int count, Delegate method)
{
Do<Exception>(count, 0, 0, method);
}
}

GeneralRe: The following helper class does this toomemberRotem Sapir3:19 3 Nov '08  
It was probably a mistake to develop before looking if someone already did the jobShucks
Thanks for the heads up. I'll take a look at your code.
Last Visit: 9:27 13 May '09     Last Update: 9:27 13 May '091

General General   News News   Question Question   Answer Answer   Joke Joke   Rant Rant   Admin Admin   

PermaLink |Privacy |Terms of Use
Last Updated: 6 Nov 2008
Editor:Deeksha Shenoy
Copyright 2008 by Rotem Sapir
Everything elseCopyright ©CodeProject, 1999-2009
Web10 |Advertise on the Code Project


[8]ページ先頭

©2009-2025 Movatter.jp