使用Delegates通过1次重试执行任何方法的通用方法

时间:2018-02-08 12:47:44

标签: c# .net delegates

我正在尝试开发一种机制,使用该机制我可以通过1次重试尝试执行任何方法。

如果在第一次运行中遇到异常,将触发重试。

基本的想法是,我将有一个用于重试逻辑的泛型类,我想通过委托传递任何方法。并且该方法将在1次重试时执行。

到目前为止,我已经开发了这个。

public class RetryHandler
{
    Delegate _methodToRetry;

    // default constructor with delegate to function name.
    public RetryHandler(Delegate MethodToExecuteWithRetry)
    {
        _methodToRetry = MethodToExecuteWithRetry;
    }

    public void ExecuteWithRetry(bool IsRetryEnabled)
    {
        try
        {
            _methodToRetry.DynamicInvoke();
        }
        catch (Exception ex)
        {
            if (IsRetryEnabled)
            {
                // re execute method.
                ExecuteWithRetry(false);
            }
            else
            {
                // throw exception
                throw;
            }
        }

    }


}

现在我遇到了一个问题:

我想传递的方法有不同的输入参数(通过参数和对象类型的数量)和不同的输出参数。

有什么办法可以实现这个目标吗?基本上我想调用这样的方法:

RetryHandler rh = new RetryHandler(MyMethod1(int a, int b));
int output = (int) rh.ExecuteWithRetry(true);

RetryHandler rh2 = new RetryHandler(MyMethod2(string a));
string output2 = (string) rh2.ExecuteWithRetry(true);

非常感谢任何帮助。谢谢。

2 个答案:

答案 0 :(得分:4)

你打电话:

public T Retry<T>(Func<T> func)
{
    try { return func(); }
    catch { return func(); }
}

这将允许您调用任何返回值的内容:

public int Test(int a, int b) => a + b;
public string Test(string a) => a + a;

void Example()
{
    Console.WriteLine(Retry(() => Test(1, 2)));
    Console.WriteLine(Retry(() => Test("a")));
}

答案 1 :(得分:2)

  1. 试试这个:

       public void ExecuteWithRetry(bool IsRetryEnabled, params object[] args)
        {
            try
            {
                _methodToRetry.DynamicInvoke(args);
            }
            catch (Exception ex)
            {
                if (IsRetryEnabled)
                {
                    // re execute method.
                    ExecuteWithRetry(false, args);
    

    并像这样打电话:int output = (int) rh.ExecuteWithRetry(true, a, b);

  2. 另一个选项是rwrite RetryHandler作为泛型方法,但是你需要为任何参数计数编写代码:

    public static TReturn ExecuteWithRetry<TReturn, TParam>(bool IsRetryEnabled, Func<TParam, TReturn> func, TParam param)
    {
        // ...
        return func(param);
        // ...
    }
    
  3. 或编写通用扩展方法,以便您可以调用:

    var f = new Func<int, int>((a) => a + 1);
    f.ExecuteWithRetry(x);
    

    扩展类:

    public static class Ext
    {
        public static TReturn ExecuteWithRetry<TReturn, TParam>(this Func<TParam, TReturn> func, TParam param)
        {
            return func(param);
        }
    }