Jon H
Jon H

Reputation: 1071

Elegant retry on effectively arbitrary call

I have a call to a remote resource, on this occasion it is a WCF one but I have a similar problem with a com call that might be useful.

I want to retry the call if certain exceptions are thrown and as there are a dozen or so calls I want to handle this more elegantly.

I thought of reflection but like a vampire I instinctively shy away from it.

This what I have

void mycall(){

            for (int i = 0; i < 5; i++)
            {
                try
                {
                    return this.innerProxy.LoadMap2(MapName);
                }
                catch (ServerTooBusyException e)
                {
                    Logger.DebugFormat("Caught ServerTooBusyException for {0}th time but retrying [{1}]", i + 1, e.Message);

                    Thread.Sleep(50);
                }
            }

// final call will fail if ServerTooBusy is thorwn here.
                    return this.innerProxy.LoadMap2(MapName);
}

As I have several calls like this it seems that I ought to be able to pass in a method pointer and a parameter array into this 'pattern'.

Any suggestions?

Upvotes: 0

Views: 96

Answers (1)

Bas
Bas

Reputation: 27095

This is indeed relatively easy in C# using a delegate. You can use a Func<T> without parameters, since you can specify an arbirary number of parameters using a lambda closure:

T Retry<T>(Func<T> method, int n) {
     for (int i = 0; i < n - 1; i++) {
        try {
           T value = method();
           return value;
        } catch (ServerTooBusyException e) {
           //...
        } 
     }
     //final call
     return method();
}

And calling the method:

void mycall() {
   var result = Retry(() => this.innerProxy.LoadMap2(MapName), 5);
}

Note that your mycall returns void, but I don't think it actually does, since you seem to return values. If you want to return void instead, use Action instead of Func<T> as a parameter.

Upvotes: 2

Related Questions