2010-07-07 4 views
0

Я использую внешнюю библиотеку автоматизации с набором API с 1 или 2 параметрами, которые случайным образом выбрасывают TargetInvocationException. Вызов этих API второй или третий раз обычно работает. Поэтому я создал два вспомогательных методы для объединения несколько Retry логикиПередача вызова метода и его параметра на другой метод

//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); 
     } 
    } 
} 

Проблемы: Если вы видите два вспомогательных методов выше, имеет то же самое тело и единственное различие заключается в unsafeMethod вызова внутри блока Try. Как избежать дублирования кода здесь, как я, возможно, придется добавить перегруженный метод, который принимает

Func<TResult> 

как другой тип параметра.

ответ

1

Просто пройти в Func<TResult> и называть его так:

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

Другими словами, инкапсулировать аргументы в самом делегатом.

+0

Спасибо, что сработало просто отлично! Я все еще пытаюсь склонить голову к делегатам. Можете ли вы предложить какие-либо книги или ссылки, которые содержат больше информации о рациональном использовании лямбда и делегатов, а не только теории? Что-то, что покрывает ситуации, подобные моей проблеме? – Snak3byte

+0

@Anunay: Боюсь, что нет, действительно ... моя собственная книга (C# in Depth) довольно много говорит о делегатах, но не для такой ситуации в частности. –

Смежные вопросы