Hello i am trying to understand how can one create a LinkedTokenSource
based on the Timeout property set using the typed HttpClient
(using IHttpClientFactory
) extension and any other CancellationToken
(s):
Registration
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("someClient",(client)=>
{
client.Timeout=Timespan.FromSeconds(15);
});
}
Usage
public class SomeService
{
private IHttpClientFactory factory;
public SomeService(IHttpClientFactory factory)
{
this.factory = factory;
}
public async Task MethodWithAggreatedToken(CancellationToken token = default)
{
CancellationToken additionalToken = token;
if (additionalToken == default)
{
CancellationTokenSource source = new CancellationTokenSource();
source.CancelAfter(Timespan.FromSeconds(10));
}
var client = factory.CreateClient("someService");
HttpRequestMessage msg = new HttpRequestMessage(.....);
using (var cts = CancellationTokenSource.CreateLinkedTokenSource(additionalToken,[DI token])
{
var response = await client.SendAsync(msg, cts.Token);
//can i created a linked token?
//and if not who gets priority :
//1.the token set via the `Timeout` property set in Startup
//2.the one injected in the `SendAsync`
}
}
}
In the case above i want to be able to set a generic Timeout
for my typed
HttpClient
which will be used in many methods.Now i want to know if :
Token
(s) above this general condition thus creating a LinkedTokenSource
CancellationToken
in the HttpClient.SendAsync
while also declaring the Timeout
property in
the services.AddHttpClient
.I want to know if i can do composition of tokens and also who gets overwritten (SendAsync
or Timeout
)
There is a way to add additional Token(s) above this general condition thus creating new LinkedTokenSource(s)
Yes, you can link as many CancellationTokenSource
as you wish. Because the CreateLinkedTokenSource
returns a CancellationTokenSource
that's why you can use chaining.
You can also link more than one CancellationTokenSource
s at the same time by using that overload which accepts params.
Who gets priority if i set a CancellationToken in the HttpClient.SendAsync while also declaring the Timeout property in the services.AddHttpClient.
The Remarks of the HttpClient's Timeout
clearly states the following:
The same timeout will apply for all requests using this HttpClient instance. You may also set different timeouts for individual requests using a CancellationTokenSource on a task. Note that only the shorter of the two timeouts will apply.
EDIT: Reflect to How do you extract token
from the HttpClient
?
In short, it is not exposed.
If you look at the source code of HttpClient (.NET Framework implementation, .NET Core implementation) then you can spot a CancellationTokenSource
private field called pendingRequestsCts
In the SendAsync / SendAsyncCore methods the pendingRequestsCts
is linked to the given operation's CancellationToken
.
In case of .NET Framework it is done by a simple CreateLinkedTokenSource
call.
On the other hand in case of .NET Core it is a bit more complicated. The PrepareCancellationTokenSource
method contains both the linked CTS and the timeout calculation.