我可以在没有 HttpClient 缓冲整个请求的情况下将 PushStreamContent 添加到 MultipartFormDataContent 吗?
Can I add PushStreamContent to MultipartFormDataContent without HttpClient buffering whole request?
我正在尝试使用 MultipartFormDataContent
在 HTTP POST 中发送一个大文件以及一些其他数据。为了分块发送文件,我使用 PushStreamContent
将文件流中的数据块写入输出流,每次写入后刷新:
PushStreamContent pushStreamContent = new PushStreamContent((stream, content, context) => {
byte[] buffer = new byte[4096];
int bytesRead;
do {
bytesRead = fileStream.Read(buffer, 0, 4096);
stream.Write(buffer, 0, bytesRead);
stream.Flush();
}
while(bytesRead != 0);
stream.Close();
});
如果我POST这个HttpContent
使用下面的代码,一切正常:
new HttpClient().PostAsync(destinationUrl, pushStreamContent);
但是,如果将这个PushStreamContent
添加到一个MultipartFormDataContent
,如下:
MultipartFormDataContent postForm = new MultipartFormDataContent {
{stringContent, "atom"},
{pushStreamContent, "binary"}
};
和 已发布,然后我在 PushStreamContent
的 lambda 中收到 OutOfMemoryException
。据推测,HttpClient
正在将MultipartFormDataContent
的整个缓冲到内存中,由于请求内容非常大而失败。我希望客户端推迟对包含的 PushStreamContent
的刷新。这可能吗?我正在使用 .NET 4.5。
正在缓冲请求,因为 HttpClient
需要知道请求的总长度才能设置 Content-Length header。 PushStreamContent
object always returns false 对于 TryComputeLength(out long)
.
因此解决方案是创建 PushStreamContent
的 sub-class, 知道它的长度:
class PushStreamContentWithLength : PushStreamContent {
public PushStreamContentWithLength(Action<Stream, HttpContent, TransportContext> onStreamAvailable, long streamLength) : base(onStreamAvailable) {
mStreamLength = streamLength;
}
readonly long mStreamLength;
protected override bool TryComputeLength(out long length) {
length = mStreamLength;
return true;
}
}
如果将其中之一添加到 MultipartFormDataContent
,数据将在 HTTP post 期间被推送到流,而不是 pre-loaded 到内存中。
我正在尝试使用 MultipartFormDataContent
在 HTTP POST 中发送一个大文件以及一些其他数据。为了分块发送文件,我使用 PushStreamContent
将文件流中的数据块写入输出流,每次写入后刷新:
PushStreamContent pushStreamContent = new PushStreamContent((stream, content, context) => {
byte[] buffer = new byte[4096];
int bytesRead;
do {
bytesRead = fileStream.Read(buffer, 0, 4096);
stream.Write(buffer, 0, bytesRead);
stream.Flush();
}
while(bytesRead != 0);
stream.Close();
});
如果我POST这个HttpContent
使用下面的代码,一切正常:
new HttpClient().PostAsync(destinationUrl, pushStreamContent);
但是,如果将这个PushStreamContent
添加到一个MultipartFormDataContent
,如下:
MultipartFormDataContent postForm = new MultipartFormDataContent {
{stringContent, "atom"},
{pushStreamContent, "binary"}
};
和 已发布,然后我在 PushStreamContent
的 lambda 中收到 OutOfMemoryException
。据推测,HttpClient
正在将MultipartFormDataContent
的整个缓冲到内存中,由于请求内容非常大而失败。我希望客户端推迟对包含的 PushStreamContent
的刷新。这可能吗?我正在使用 .NET 4.5。
正在缓冲请求,因为 HttpClient
需要知道请求的总长度才能设置 Content-Length header。 PushStreamContent
object always returns false 对于 TryComputeLength(out long)
.
因此解决方案是创建 PushStreamContent
的 sub-class, 知道它的长度:
class PushStreamContentWithLength : PushStreamContent {
public PushStreamContentWithLength(Action<Stream, HttpContent, TransportContext> onStreamAvailable, long streamLength) : base(onStreamAvailable) {
mStreamLength = streamLength;
}
readonly long mStreamLength;
protected override bool TryComputeLength(out long length) {
length = mStreamLength;
return true;
}
}
如果将其中之一添加到 MultipartFormDataContent
,数据将在 HTTP post 期间被推送到流,而不是 pre-loaded 到内存中。