c#-什么是在Servicestack JsonServiceClient Get方法上实现重试的最佳解决方案?

在我的项目中,我使用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.如果您要专门处理这种情况.

希望对您有所帮助.

上一篇:C#-ServiceStack支持压缩的请求正文


下一篇:带有一台RabbitMQ服务器的多个ServiceStack应用程序