.net - 使用 HttpClient 上传大负载而无需缓冲
问题描述
我正在使用 HttpClient 发送包含大型多部分有效负载的 POST 请求。事实证明 HttpClient 正在缓冲整个请求,并且通过尝试发送大文件来重新创建内存不足错误非常容易。HttpClient 为构建多部分有效负载提供了一个很好的框架,但是否可以阻止它缓冲请求?
我正在使用 .net 4.7.2
编辑:
我什至尝试过 PushStreamContent:
byte[] binBuffer = new byte[4096];
int iRead = 0;
PushStreamContent partAttachment = new PushStreamContent((stream, content, context) =>
{
using (Stream strData = File.Open(@"c:\test\big.csv", FileMode.Open, FileAccess.Read, FileShare.Read))
{
while ((iRead = strData.Read(binBuffer, 0, binBuffer.Length)) > 0)
{
stream.Write(binBuffer, 0, iRead);
};
}
stream.Close();
});
我在流上遇到 OOM 异常。一旦我打了大约 2 个演出就写。
解决方案
PushStreamContent 将允许您发送字节流而无需缓冲。
var httpClient = new HttpClient();
var request = new HttpRequestMessage() {
RequestUri = ... ,
Method = HttpMethod.POST,
Content = new PushStreamContent(async (stream, httpContent, transportContext) =>
{
// write to the stream from where ever you are getting the bytes from
stream.Close();
})
};
await httpClient.SendAsync(request);
您可以从这里https://github.com/aspnet/AspNetWebStack/blob/master/src/System.Net.Http.Formatting/PushStreamContent.cs#L113看到所有 PushStreamContent 所做的就是它通过 HttpClientHandler 接收网络流SerializeToStream 方法并允许您直接写入它。
我有一个模糊的回忆,早期版本的 .NET 4 存在实际上阻止使用分块传输编码的问题。我记得它是固定的,但我不是 100% 确定它。如果分块编码不起作用,则问题出在管道的 HttpClientHandler 端,而不是在 HttpClient 或 PushStreamContent 中。
推荐阅读
- jenkins - 是否可以组合或混合 Jenkins 声明式和脚本化管道?
- android - 如何使用带有 onSwiped 的 FirebaseRecyclerAdapter 从 recyclerview 和数据库中删除项目?
- reactjs - 使用 heremap 多次拾取和多次放置 api 遇到问题
- python - 在 Python 中使用 json.dump 将“漂亮”的 JSON 对象保存到光盘
- ruby-on-rails - Rails未定义的局部变量或常量内的方法
- php - 为什么我的 mySql 代码需要很长时间才能执行?
- database - 如何使用 sequelize 和 nodejs 在 sqlite3 中设计无穷大?
- python - 旋转 Pyspark DataFrame 以获取 MultiColumn
- azure - 路由到 Azure Front Door 后面的多个 Web 应用
- python - 更改字符串值