I have my web requests handled by this code;
Response = await Client.SendAsync(Message, HttpCompletionOption.ResponseHeadersRead, CToken);
That returns after the response headers are read and before the content is finished reading. When I call this line to get the content...
return await Response.Content.ReadAsStringAsync();
I want to be able to stop it after X seconds. But it doesn't accept a cancellation token.
Have a look at How do I cancel non-cancelable async operations?. If you just want the
await
to finish while the request continues in the background you can use the author'sWithCancellation
extension method. Here it is reproduced from the article:It essentially combines the original task with a task that accepts a cancellation token and then awaits both tasks using
Task.WhenAny
. So when you cancel theCancellationToken
the secodn task gets cancelled but the original one keeps going. As long as you don't care about that you can use this method.You can use it like this:
Update
You can also try to dispose of the Response as part of the cancellation.
Now as you cancel the token, the
Content
object will be disposed.Since returns a task, you can
Wait
for the Task which essentially is equivalent to specifying a timeout:While you can rely on
WithCancellation
for reuse purposes, a simpler solution for a timeout (which doesn't throwOperationCanceledException
) would be to create a timeout task withTask.Delay
and wait for the first task to complete usingTask.WhenAny
:Or, if you want to throw an exception in case there's a timeout instead of just returning the default value (i.e.
null
):And the usage would be: