使用委托重试一次即可执行任何方法的通用方法

Bug*_*der 5 .net c# delegates

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

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

基本思想是,我将有一个用于重试逻辑的通用类,并且我想通过委托在其中传递任何方法。并且该方法将执行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;
            }
        }

    }


}
Run Code Online (Sandbox Code Playgroud)

现在我有一个问题:

我要传递的方法具有不同的输入参数(按参数数量和对象类型分别)和不同的输出参数。

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

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);
Run Code Online (Sandbox Code Playgroud)

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

gab*_*bba 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);
    
    Run Code Online (Sandbox Code Playgroud)

    并像这样调用: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);
        // ...
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 或者编写通用扩展方法,以便您可以调用:

    var f = new Func<int, int>((a) => a + 1);
    f.ExecuteWithRetry(x);
    
    Run Code Online (Sandbox Code Playgroud)

    扩展类:

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