如何复制HttpContent async和cancelable?

Kru*_*lur 9 .net c# async-await dotnet-httpclient xamarin

我正在使用HttpClient.PostAsync(),响应是一个HttpResponseMessage.其Content属性是HttpContent具有CopyToAsync()方法的类型.不幸的是,这是不可取消的.有没有办法将响应复制到a Stream并传递CancellationToken

我没有被困住CopyToAsync()!如果有解决方法,那就没问题了.就像读取几个字节一样,检查是否取消,继续阅读等等.

这些HttpContent.CreateContentReadStreamAsync()方法看起来像是候选人.不幸的是,它不适用于我选择的个人资料.还不清楚它是否会一次性读取所有数据并浪费大量内存.

注意:我在PCL中使用这个目标是WP8,Windows Store 8,.NET 4.5,Xamarin.iOS和Xamarin.Android

Ste*_*ary 15

我相信这应该有效:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,对于流响应的ReadAsStreamAsync调用CreateContentReadStreamAsync只返回基础内容流而不将其缓冲到内存中.

  • 我使用了一个变体来确保使用SendAsync而不是PostAsync来传输响应内容.使用SendAsync时,必须使用HttpCompletionOption.ResponseHeadersRead参数,否则SendAsync调用在读取整个响应之前不会返回,包括所有内容(MB,GB等) - 即不可取,因为所有数据都被读入内存(可以在任务管理器中看到内存使用).使用HttpCompletionOption.ResponseHeadersRead意味着可以正确地流式传输数据.我不确定PostAsync采用哪种方式,但希望这些信息可以帮助其他人. (5认同)