使用多种方法重试逻辑
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);
}
我正在客户端实现 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);
}