Click here to Skip to main content
Click here to Skip to main content

Automating Retry on Exception

, 7 Jun 2012
Rate this:
Please Sign up or sign in to vote.
How to automate Retry on Exception.

Every so often, you run across some action, which just fails, where the best response it to just try it again. This is particularly true when dealing with an external source, like a database or web service, which can have network or other temporary problems, which would have cleared up when you repeat the call seconds later. Often, these actions fail by throwing an exception which makes the process of trying the call again rather cumbersome. Having to deal with this a number of times in one application, I decided to wrap the full procedure up in a method, which I share here with you:

OK, this has very weird semantics. A call will look something like this:

var msg = Util.Retry(5, 1,
            ( ) => "Error",
            AppLog.Log,   // assuming there is an AppLog.Log(Exception ex) method.
            ( ) =>
            {
                    // Simulation of a function which fails & succeeds at random times
                    Console.WriteLine(DateTime.Now.ToLongTimeString());
                    if ((DateTime.Now.Second & 7) != 7)
                    throw new Exception("Bad");
                    return DateTime.Now.ToString();
            });

The first parameter is the maximum num of time to retry the call before giving up.

The second parameter is the time, in seconds, to wait between retries.

The third parameter is a function (or lambda expression) taking no parameters, and returning the value to return in case of failure. It done as a function to avoid evaluating it unless needed, in case it was a heavy-weight object, or had some side-effect.

The fourth parameter (made optional by way of an overload) is a function (or lambda expression) taking an exception as a parameter, and returning nothing. Can be used to log the final exception on it gives up retrying.

The last parameter is a function (or lambda expression) taking no parameters, which performs the actual work which may need to be retried.

The code looks like this:

static public T Retry<T>(int retries, int secsDelay, Func<T> errorReturn, 
       Action<Exception> onError,  Func<T> code)
{
    Exception ex = null;
    do
    {
        try
        {
            return code();
        }
        catch (Exception dde)
        {
            ex = dde;
            retries--;
            Thread.Sleep(secsDelay * 1000);
        }
    } while (retries > 0);
    onError(ex);
    return errorReturn();
}

The full source code (with comments and everything!) is here.

License

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

About the Author

James Curran
Web Developer AFS Technologies
United States United States
20+ years as a developer : Assembly, C, C++ and C# (in that order) with sidelines in ASP/VBScript, ASP.Net, JavaScript, Perl, QuickBasic, VisualBasic, plus a few others which I'm not going to mention because if I did someone might ask me to use them again (shudder)
 
Microsoft MVP in VC++ (1994-2004)
 
I also run www.NJTheater.com as a hobby.
 
Full resume & stuff at NovelTheory.com
 
Underused blog at HonestIllusion.com
Follow on   Twitter

Comments and Discussions

 
GeneralThis approach is indiscriminate PinmemberJohn Brett10-Jun-12 21:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 7 Jun 2012
Article Copyright 2012 by James Curran
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid