在我的项目中,我使用Servicestack从特定的URL提取数据,此过程是可配置的,我在单独的线程中调用提取数据,如果发生超时错误,我想实现重试.我在JsonServiceClient上创建了包装器类,并在此实现重试,但是我想知道什么是此方法的最佳解决方案.
var _client = new JsonServiceClient { Timeout = timeout };
var counter = 0;
do
{
try
{
result = _client.Get<TResponse>(url);
break;
}
catch (Exception exp)
{
//Logging exception
}
}
while (++counter < this.Retry);
解决方法:
I created wrapper class on JsonServiceClient and implement retry there, but I want to know what’s the best solution for this approach.
我同意你的做法.扩展JsonServiceClient并实现您的重试逻辑,如果实现了以下类似的东西,则是实现可重用性和可维护性的最佳方法.
扩展JsonServiceClient
扩展JsonServiceClient,以便您可以合并自己的重试逻辑.这样,您便可以轻松地在代码中重复使用它,而无需在每次要发出请求时都使用while和counters.
如果您在此处看到JsonServiceClientBase.cs
代码,则会注意到所有动词方法(如Get< TResponse>)都已使用. Post< TResponse> …通过Send< TResponse>(对象请求)方法进行所有调用.
因此,通过覆盖此方法,我们可以轻松地对所有动词实施重试功能,而无需更改其用法.
public class MyJsonServiceClientWithRetry : JsonServiceClient
{
public MyJsonServiceClientWithRetry()
{
}
public MyJsonServiceClientWithRetry(int retryAttempts)
{
RetryAttempts = retryAttempts;
}
public MyJsonServiceClientWithRetry(string baseUri) : base(baseUri)
{
}
public MyJsonServiceClientWithRetry(string syncReplyBaseUri, string asyncOneWayBaseUri) : base(syncReplyBaseUri, asyncOneWayBaseUri)
{
}
// Retry attempts property
public int RetryAttempts { get; set; }
public override TResponse Send<TResponse> (string httpMethod, string relativeOrAbsoluteUrl, object request)
{
int attempts = RetryAttempts;
while(true)
{
attempts--;
try {
return base.Send<TResponse> (httpMethod, relativeOrAbsoluteUrl, request);
} catch (WebServiceException webException) {
// Throw the exception if the number of retries is 0 or we have made a bad request, or are unauthenticated
if(attempts == 0 || webException.StatusCode == 400 || webException.StatusCode == 401)
throw;
} catch (Exception exception) {
// Throw the exception if the number of retries is 0
if(attempts == 0)
throw;
}
}
}
}
用法:
>用MyJsonServiceClientWithRetry替换对JsonServiceClient的引用
>设置尝试次数
>正常使用客户端. (在try / catch块中包装以在超出重试次数后捕获异常)
var client = new MyJsonServiceClientWithRetry ("http://localhost:8080") {
RetryAttempts = 3,
Timeout = new TimeSpan(0, 0, 30)
};
try
{
var myRequestDto = new MyRequest {
Name = "John Smith"
};
// This request will be attempted 3 times (if there is an exception)
var response = client.Get<MyResponse>(myRequestDto);
// Do something with response ...
} catch(Exception ex) {
// Exception thrown here after 3 attempts (or immediately if status code is 400 / 401)
}
笔记:
我不会重试是否抛出状态代码为400或401的WebServiceException,因为重新尝试此请求而不更改它似乎是多余的.显然,您可以自定义此逻辑.
如果连接超时,则超时错误将抛出WebException
.如果您要专门处理这种情况.
希望对您有所帮助.