使用多种方法重试逻辑

Retry logic with multiple methods

我正在客户端实现 WCF 服务的重试逻辑。 我在 WCF 服务中有多个操作,具有各种输入参数和 return 类型。

我创建了一个包装器,它可以使用 Action 委托调用这些没有 return 类型 (void) 的特定方法。有什么方法可以调用具有各种输入参数和 return 类型的方法。

或者是否有任何逻辑可以在可以处理多个 WCF 服务的客户端实现重试功能。

Class RetryPolicy<T>
{
 public T ExecuteAction(Func<T> funcdelegate,int? pretrycount = null,bool? pexponenialbackoff = null)
        {
            try
            {
                var T = funcdelegate();
                return T;
            }
            catch(Exception e)
            {
                if (enableRetryPolicy=="ON" && TransientExceptions.IsTransient(e))
                {

                    int? rcount = pretrycount == null ? retrycount : pretrycount;
                    bool? exbackoff = pexponenialbackoff == null ? exponentialbackoff : pexponenialbackoff;

                    int rt = 0;
                    for (rt = 0; rt < rcount; rt++)
                    {
                        if (exponentialbackoff)
                        {
                            delayinms = getWaitTimeExp(rt);
                        }

                        System.Threading.Thread.Sleep(delayinms);

                        try
                        {
                            var T = funcdelegate();
                            return T;
                        }
                        catch(Exception ex)
                        {
                            if (TransientExceptions.IsTransient(ex))
                            {

                                int? rcount1 = pretrycount == null ? retrycount : pretrycount;
                                bool? exbackoff1 = pexponenialbackoff == null ? exponentialbackoff : pexponenialbackoff;

                            }
                            else
                            {
                                throw;
                            }
                        }
                    }

                    //throw exception back to caller if exceeded number of retries
                    if(rt == rcount)
                    {
                        throw;
                    }
                }
                else
                {
                    throw;
                }
            }
            return default(T);
        }
}  

我用上面的方法打电话

  public string GetCancelNumber(string property, Guid uid)
        {
            RetryPolicy<string> rp = new RetryPolicy<string>();
            return rp.ExecuteAction(()=>Channel.GetCancelNumber(property, uid, out datasetarray));
        }

我一直收到错误 "cannot use ref or out parameters in anonymous delegate"

这里是一个简单的重试方法的例子:

bool Retry(int numberOfRetries, Action method)
{
    if (numberOfRetries > 0)
    {
        try
        {
            method();
            return true;
        }
        catch (Exception e)
        {
            // Log the exception
            LogException(e); 

            // wait half a second before re-attempting. 
            // should be configurable, it's hard coded just for the example.
            Thread.Sleep(500); 

            // retry
            return Retry(--numberOfRetries, method);
        }
    }
    return false;
}

如果该方法至少成功一次,它将 return 为真,并在此之前记录任何异常。 如果该方法在每次重试时都失败,它将 return false。

(在这种情况下成功意味着完成,没有抛出异常)

使用方法:

假设示例 Action(void 方法)和示例 Func(具有 return 类型的方法)

void action(int param) {/* whatever implementation you want */}
int function(string param) {/* whatever implementation you want */}

执行函数:

int retries = 3;
int result = 0;
var stringParam = "asdf";
if (!Retry(retries, () => result = function(stringParam)))
{
    Console.WriteLine("Failed in all {0} attempts", retries);
}
else
{
    Console.WriteLine(result.ToString());
}

执行一个动作:

int retries = 7;
int number = 42;
if (!Retry(retries, () => action(number)))
{
    Console.WriteLine("Failed in all {0} attempts", retries);
}
else
{
    Console.WriteLine("Success");
}

执行带有输出参数的函数 (int function(string param, out int num)):

int retries = 3;
int result = 0;
int num = 0;
var stringParam = "asdf";
if (!Retry(retries, () => result = function(stringParam, out num)))
{
    Console.WriteLine("Failed in all {0} attempts", retries);
}
else
{
    Console.WriteLine("{0} - {1}", result, num);
}