首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展HttpClient

扩展HttpClient
EN

Stack Overflow用户
提问于 2013-03-30 16:03:44
回答 2查看 8.3K关注 0票数 4

我正在尝试创建一个扩展httpclient但仍然是抽象的类。

代码语言:javascript
复制
public abstract class Repository : HttpClient
{
    public override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        //retry logic here
        var response = await base.SendAsync(request, cancellationToken);
        while (!IsValid(response))
        {
            Attempts++;
            response = await Retry(request, cancellationToken);
        }
        Attempts = 0;
        return response;
    }
    public int Attempts { get; set; }
    public abstract bool IsValid(HttpResponseMessage response);
    public abstract Task<HttpResponseMessage> Retry(HttpRequestMessage request, CancellationToken cancellationToken);
    public abstract Type GetPageForUri(Uri uri);
    public abstract Task<object> GetItems(Uri uri);
}

但是,当子类调用getStringAsync时,它不会调用存储库中的SendAsync

代码语言:javascript
复制
public class EmailClient : Repository
{
    public override bool IsValid(HttpResponseMessage response)
    {
        return response.IsSuccessStatusCode;
    }
    public override Task<HttpResponseMessage> Retry(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return base.SendAsync(request, cancellationToken);
    }
    public override Type GetPageForUri(Uri uri)
    {
        return typeof(EmailPage);
    }
    public override async Task<object> GetItems(Uri uri)
    {
        var emails = await GetStringAsync(uri);
        return emails;
    }
}

我哪里做错了?我是否应该制作一个HttpClientHandler并将其包含在HttpClient中?我试着阅读有关虚拟的文章,如果这有什么不同的话。但是我不明白为什么它没有被调用。有谁可以帮我?

EN

回答 2

Stack Overflow用户

发布于 2016-04-14 07:13:04

HttpClient是HttpMessageHandler实现(通常是HttpClientHandler,它是大多数运行时实现都支持的特性的属性)的薄包装器。

实际上有一个用于装饰器的HttpMessageHandler基类,比如重试场景DelegatingHandler,您可以像这样实现它:

类似于:

代码语言:javascript
复制
public class RetryMessageHandler : DelegatingHandler
{
    readonly int retryCount;

    public RetryMessageHandler(int retryCount)
        : this(new HttpClientHandler(), retryCount)
    {
    }

    public RetryMessageHandler(HttpMessageHandler innerHandler, int retryCount)
        : base(innerHandler)
    {
        this.retryCount = retryCount;
    }

    public override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpResponseMessage response = null;

        for (int i = 0; i<=retryCount; i++)
        {
            response = await base.SendAsync(request, cancellationToken);

            if (response.IsSuccessStatusCode)
            {
                return response;
            }
        }

        return response;
    }
}

然后您可以像这样使用它:

代码语言:javascript
复制
HttpClient httpClient = HttpClientFactory.CreatePipeline(new HttpClientHandler(), 
    new [] { new RetryMessageHandler(3) });

var response = await httpClient.SendAsync(request);

此外,我建议您的EmailClient包装/依赖于HttpClient,而不是扩展它。(有关原因的更多信息,请使用谷歌“组合与继承”)

票数 10
EN

Stack Overflow用户

发布于 2019-06-28 13:04:04

response = await base.SendAsync(request,cancellationToken);没有返回任何东西,请永远等待,使用.configureawait(false)是一个好的实践吗?

票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15716399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档