views:

51

answers:

1

I am using an external automation library with bunch of APIs with either 1 or 2 parameters which randomly throws TargetInvocationException. Calling these APIs second or third time usually works. I therefore created two helper methods to encapsulate the multiple retry logic

//Original API calls
bool result1 = Foo1(true);
int result2 = Foo2(4, "abc");

//New API calls
bool result1 = SafeMethodCall(Foo1, true);
int result2 = SafeMethodCall(Foo2, 4, "abc");


//Helper Methods
public static TResult SafeMethodCall<T, TResult>(
    Func<T, TResult> unSafeMethod,
    T parameter)
{
    int numberOfMethodInvocationAttempts = 3;
    int sleepIntervalBetweenMethodInvocations = 10000;

    for (int i = 0; i < numberOfMethodInvocationAttempts; i++)
    {
        try
        {
            return unSafeMethod(parameter);
        }
        catch (System.Reflection.TargetInvocationException ex)
        {
            System.Threading.Thread.Sleep(sleepIntervalBetweenMethodInvocations);
        }
    }
}

public static TResult SafeTargetInvocationMethodCall<T1, T2, TResult>(
    Func<T1, T2, TResult> unSafeMethod,
    T1 parameter1,
    T2 parameter2)
{
    int numberOfMethodInvocationAttempts = 3;
    int sleepIntervalBetweenMethodInvocations = 10000;

    for (int i = 0; i < numberOfMethodInvocationAttempts; i++)
    {
        try
        {
            return unSafeMethod(parameter1, parameter2);
        }
        catch (System.Reflection.TargetInvocationException ex)
        {
            System.Threading.Thread.Sleep(sleepIntervalBetweenMethodInvocations);
        }
    }
}

Problem: If you see the two helper methods above have the same body and the only difference is unsafeMethod call inside the try block. How can I avoid code duplication here as I might have to add a overloaded method that accepts

Func<TResult>

as another parameter type.

+1  A: 

Just pass in Func<TResult> and call it like this:

bool result1 = SafeMethodCall(() => Foo1(true));
int result2 = SafeMethodCall(() => Foo2(4, "abc"));

In other words, encapsulate the arguments in the delegate itself.

Jon Skeet
Thanks that worked just great! I'm still trying to wrap my head around delegates. Can you suggest any books or links which have more info on pratical usage of lambdas and delegates rather than just the theory? Something that covers situations similar to my problem?
Anunay
@Anunay: I'm afraid not, really... my own book (C# in Depth) does talk quite a lot about delegates, but not for this sort of situation in particular.
Jon Skeet