I'm using HttpClient.PostAsync()
and the response is an HttpResponseMessage
. Its Content property is of type HttpContent
which has a CopyToAsync()
method. Unfortunately, this is not cancelable.
Is there a way to get the response copied into a Stream
and pass a CancellationToken
?
I am not stuck with CopyToAsync()
! If there is a workaround, that would be fine. Like read a couple of bytes, check if canceled, continue reading and so on.
The HttpContent.CreateContentReadStreamAsync()
methods looks like it would be a candidate. Unfortunately, it's not available with my selected profile. Also unclear if it would read all data in one go and waste a lot of memory.
Note: I'm using this inside a PCL targeting WP8, Windows Store 8, .NET 4.5, Xamarin.iOS and Xamarin.Android
I believe this should work:
public static async Task DownloadToStreamAsync(string uri, HttpContent data, Stream target, CancellationToken token)
{
using (var client = new HttpClient())
using (var response = await client.PostAsync(uri, data, token))
using (var stream = await response.Content.ReadAsStreamAsync())
{
await stream.CopyToAsync(target, 4096, token);
}
}
Note that ReadAsStreamAsync
calls CreateContentReadStreamAsync
, which for stream responses just returns the underlying content stream without buffering it into memory.
You can't cancel a non cancellable operation. See How do I cancel non-cancelable async operations?.
You can however allow your code flow to behave as if the underlying operation was canceled, with WithCancellation
.
public static Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
{
return task.IsCompleted
? task
: task.ContinueWith(
completedTask => completedTask.GetAwaiter().GetResult(),
cancellationToken,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Default);
}
Usage:
await httpContent.PostAsync(stream).WithCancellation(new CancellationTokenSource(1000).Token);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With