下面是我在Oracle应用程序中的代码,其中处理了与C#、FTP和Null引用异常的连接:
public Result Execute()
{
Result result = null;
string errorMessage = string.Empty;
var retryTimes = 1000;
var retryableErrorCodes = new[] { "ORA-03113", "ORA-03114", "ORA-12543",
"ORA-12170", "ORA-12154", "ORA-12541", "ORA-12560", "ORA-03135",
"Connection request timed out" };
var retryExceptionError = new[] { "Object reference not set to an instance of an object" };
RetryPolicy retryPolicyFTP = Policy
.Handle<Xceed.Ftp.FtpInvalidStateException>().Or<Xceed.Ftp.FtpIOException>()
.WaitAndRetry(retryTimes, _ => TimeSpan.FromSeconds(1));
RetryPolicy retryPolicyOracle = Policy
.Handle<OracleException>(ex => retryableErrorCodes.Any(errorCode => ex.Message.ToString().Contains(errorCode)))
.WaitAndRetry(retryTimes, _ => TimeSpan.FromSeconds(1));
RetryPolicy retryException = Policy
.Handle<Exception>(ex => retryExceptionError.Any(errorCode => ex.Message.ToString().Contains(errorCode)))
.WaitAndRetry(retryTimes, _ => TimeSpan.FromSeconds(1));
Policy.Wrap(retryPolicyFTP, retryPolicyOracle, retryException).Execute(() =>
{
//few lines of C# Code like fetching details from Database
if(some condition)
{
//Some Operations
return new Result(ResultType.Failure, "This function has Failed");
}
if(some other condition)
{
//Some Operations
return new Result(ResultType.Success, "This function is Successful");
}
//Some more lines of C# Code
});
return Result.Successful;
}使用这段代码,我不能在函数的中间使用return关键字,因为Polly框架不允许它这样做。
请您建议在函数中间处理return关键字的更好方法是什么?
发布于 2021-07-21 13:43:59
在Polly中,您可以为方法和函数定义装饰器。
对于方法,重试策略应该定义如下:
RetryPolicy retryPolicyFTP = Policy
.Handle<Xceed.Ftp.FtpInvalidStateException>().Or<Xceed.Ftp.FtpIOException>()
.WaitAndRetry(retryTimes, _ => TimeSpan.FromSeconds(1));对于函数,应该像这样定义重试策略:
RetryPolicy<Result> retryPolicyFTP = Policy<Result>
.Handle<Xceed.Ftp.FtpInvalidStateException>().Or<Xceed.Ftp.FtpIOException>()
.WaitAndRetry(retryTimes, _ => TimeSpan.FromSeconds(1));您应该在这里发现的<Result>部件在lhs和rhs以及。
有了这些知识,您的方法可以重写如下:
public Result Execute()
{
Result result = null;
string errorMessage = string.Empty;
var retryTimes = 1000;
var retryableErrorCodes = new[] { "ORA-03113", "ORA-03114", "ORA-12543", "ORA-12170", "ORA-12154", "ORA-12541", "ORA-12560", "ORA-03135", "Connection request timed out" };
var retryExceptionError = new[] { "Object reference not set to an instance of an object" };
RetryPolicy<Result> retryPolicyFTP = Policy<Result>
.Handle<Xceed.Ftp.FtpInvalidStateException>().Or<Xceed.Ftp.FtpIOException>()
.WaitAndRetry(retryTimes, _ => TimeSpan.FromSeconds(1));
RetryPolicy<Result> retryPolicyOracle = Policy<Result>
.Handle<OracleException>(ex => retryableErrorCodes.Any(errorCode => ex.Message.ToString().Contains(errorCode)))
.WaitAndRetry(retryTimes, _ => TimeSpan.FromSeconds(1));
RetryPolicy<Result> retryException = Policy<Result>
.Handle<Exception>(ex => retryExceptionError.Any(errorCode => ex.Message.ToString().Contains(errorCode)))
.WaitAndRetry(retryTimes, _ => TimeSpan.FromSeconds(1));
Result res = Policy.Wrap(retryPolicyFTP, retryPolicyOracle, retryException).Execute(() =>
{
if (some condition)
{
return new Result(ResultType.Failure, "This function has Failed");
}
if (some other condition)
{
return new Result(ResultType.Success, "This function is Successful");
}
return Result.Successful;
});
return res;
}因为您的Execute必须返回一个Result,所以Result.Successful可以移动到Execute块中。
我还建议将战略声明和执行分开如下:
public Result Execute()
{
...
var strategy = Policy.Wrap(retryPolicyFTP, retryPolicyOracle, retryException)
return strategy.Execute(() =>
{
if (some condition)
{
return new Result(ResultType.Failure, "This function has Failed");
}
if (some other condition)
{
return new Result(ResultType.Success, "This function is Successful");
}
return Result.Successful;
});
}https://stackoverflow.com/questions/68470069
复制相似问题