使用 HttpClientHandler 设置超时
Set timeout with HttpClientHandler
我正在尝试使用 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);
我看不到任何可用于设置超时的属性。如何设置超时时间?
上面的评论是正确的。 AngleSharp 正在将请求者抽象出来——以允许多种类型的请求者并在需要时提供灵活性。基本接口是 IRequester
(注意:故意没有 HTTP - 在 AngleSharp.Io 中我们还发现,例如,一个 FileRequester
访问本地文件系统的 file:// URI) .
我们现在可以实现我们自己的请求器,或者只使用来自 AngleSharp.Io 的 HttpClientRequester
以及接受 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();
希望对您有所帮助!
有时需要在 HttpClient
和 HttpClientHandler
级别上设置不同的超时,例如某种重试逻辑,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(...);
我正在尝试使用 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);
我看不到任何可用于设置超时的属性。如何设置超时时间?
上面的评论是正确的。 AngleSharp 正在将请求者抽象出来——以允许多种类型的请求者并在需要时提供灵活性。基本接口是 IRequester
(注意:故意没有 HTTP - 在 AngleSharp.Io 中我们还发现,例如,一个 FileRequester
访问本地文件系统的 file:// URI) .
我们现在可以实现我们自己的请求器,或者只使用来自 AngleSharp.Io 的 HttpClientRequester
以及接受 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();
希望对您有所帮助!
有时需要在 HttpClient
和 HttpClientHandler
级别上设置不同的超时,例如某种重试逻辑,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(...);