Reputation: 14926
I am trying to set the timeout value of anglesharp.io using HttpClientHandler.
This issue suggests it is possible: https://github.com/AngleSharp/AngleSharp/issues/266
I am getting page like this:
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);
I cannot see any properties available to set the timeout. How do I set the timeout?
Upvotes: 1
Views: 7869
Reputation: 3189
The comments above are right. AngleSharp is abstracting requesters away - to allow multiple types of requesters and provide flexibility if needed. The essential interface is IRequester
(note: there is no HTTP on purpose - in AngleSharp.Io we also find, e.g., a FileRequester
that accesses the local file system for file:// URIs).
We could now either implement our own requester or just use the HttpClientRequester
from AngleSharp.Io with the constructor overload accepting an HttpClient
instance.
var client = new HttpClient();
client.Timeout = MyCustomTimeout; //Whatever value you want it to be
var requester = new HttpClientRequester(client);
Now the question is how can you use this requester? We just create a configuration (as usual) and use the default loader extension method (as usual), however, this time with our custom requester.
For pre 0.10 this looks as follows:
// Assumes we do not want to provide custom options for the loaders
var requesters = new [] { requester };
var configuration = Configuration.Default.WithDefaultLoader(requesters: requesters);
For 0.10 and later this looks a bit different:
var configuration = Configuration.Default.WithRequester(requester).WithDefaultLoader();
Hope this helps!
Upvotes: 2
Reputation: 4408
Sometimes it's needed to have different timeouts on the level of HttpClient
and HttpClientHandler
, for example kind of retry logic, seamless for HttpClient
- wait for 5 minutes, but retry every minute. In this case one can use a delegating handler like following:
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;
}
}
}
Use case:
var client = new HttpClient(
new RetryHandler(TimeSpan.FromMinutes(1)))
{
Timeout = TimeSpan.FromMinutes(5)
};
client.PostAsync(...);
Upvotes: 0