1

我正在尝试使用 HttpClientHandler 设置anglesharp.io 的超时值。

这个问题表明它是可能的:https ://github.com/AngleSharp/AngleSharp/issues/266

我得到这样的页面:

        NetworkCredential proxyCreds = new NetworkCredential(proxy.User, proxy.Pass);

        WebProxy wProxy = new WebProxy(proxy.Ip + ":" + proxy.Port, false)
        {
            UseDefaultCredentials = false,
            Credentials = proxyCreds,
        };

        HttpClientHandler httpClientHandler = new HttpClientHandler()
        {
            Proxy = wProxy,
            PreAuthenticate = true,
            UseDefaultCredentials = false
        };

        var config = Configuration.Default.WithRequesters(httpClientHandler);

        var document = await BrowsingContext.New(config).OpenAsync(address);

我看不到任何可用于设置超时的属性。如何设置超时?

4

2 回答 2

2

上面的评论是对的。AngleSharp 将请求者抽象出来——以允许多种类型的请求者并在需要时提供灵活性。基本接口是IRequester(注意:没有故意使用 HTTP - 在 AngleSharp.Io 中,我们还发现,例如,一个FileRequester访问本地文件系统的文件:// URI)。

我们现在可以实现我们自己的请求者,或者只使用HttpClientRequester来自 AngleSharp.Io 的构造函数重载接受一个HttpClient实例。

var client = new HttpClient();
client.Timeout = MyCustomTimeout; //Whatever value you want it to be
var requester = new HttpClientRequester(client);

现在的问题是如何使用这个请求者?我们只是创建一个配置(像往常一样)并使用默认的加载器扩展方法(像往常一样),但是这次使用我们的自定义请求器。

对于 0.10 之前的版本,如下所示:

 // Assumes we do not want to provide custom options for the loaders
 var requesters = new [] { requester };
 var configuration = Configuration.Default.WithDefaultLoader(requesters: requesters);

对于 0.10 及更高版本,这看起来有点不同:

 var configuration = Configuration.Default.WithRequester(requester).WithDefaultLoader();

希望这可以帮助!

于 2017-12-11T21:10:23.083 回答
0

有时需要在 和 级别上有不同的超时HttpClientHttpClientHandler例如重试逻辑,无缝HttpClient等待 5 分钟,但每分钟重试一次。在这种情况下,可以使用如下委托处理程序:

public class RetryHandler : DelegatingHandler
{
    private readonly TimeSpan timeout;

    public RetryHandler(TimeSpan timeout)
    {
        this.timeout = timeout;
    }

    private async Task<HttpResponseMessage> Delay(
        CancellationToken cancellationToken)
    {
        await Task.Delay(timeout, cancellationToken);

        return null;
    }

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        for (; ; )
        {
            cancellationToken.ThrowIfCancellationRequested();

            var delayTask = Delay(cancellationToken);
            var firstCompleted = await Task.WhenAny(
                base.SendAsync(request, cancellationToken), delayTask);

            if (firstCompleted != delayTask)
                return await firstCompleted;
        }
    }
}

用例:

var client = new HttpClient(
new RetryHandler(TimeSpan.FromMinutes(1)))
{
    Timeout = TimeSpan.FromMinutes(5)
};

client.PostAsync(...);
于 2019-04-12T16:05:35.167 回答