我可以在没有HttpClient缓冲整个请求的情况下将PushStreamContent添加到MultipartFormDataContent吗?

时间:2016-09-02 10:37:05

标签: c# .net post multipartform-data dotnet-httpclient

我正在尝试使用$data['service'] = array(); $sql= "SELECT * FROM services"; $serviceDetails= mysql_query($sql); while($row = mysql_fetch_array($serviceDetails, MYSQL_ASSOC)) { $data['service'][]=$row['service_name'] } echo $twig->render('test.html',$data); 在HTTP POST中发送大文件以及其他一些数据。要以块的形式发送文件,我使用MultipartFormDataContent将文件流中的数据块写入输出流,每次写入后刷新:

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(); }); ,一切正常:

HttpContent

但是,如果将此new HttpClient().PostAsync(destinationUrl, pushStreamContent); 添加到PushStreamContent,则如下所示:

MultipartFormDataContent

发布,然后我在MultipartFormDataContent postForm = new MultipartFormDataContent { {stringContent, "atom"}, {pushStreamContent, "binary"} }; 的lambda中收到OutOfMemoryException。据推测,PushStreamContent正在缓存HttpClient整个到内存中,因为请求内容非常大而失败。我希望客户端推迟清除包含的MultipartFormDataContent。这可能吗?我使用的是.NET 4.5。

1 个答案:

答案 0 :(得分:2)

请求正在缓冲,因为HttpClient需要知道请求的总长度才能设置Content-Length标头。 PushStreamContent的{​​{1}}对象always returns false

因此,解决方案是创建一个TryComputeLength(out long)的子类, 知道它的长度:

PushStreamContent

如果将其中一个添加到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; } } ,则会在HTTP帖子中将数据推送到流中,而不是预先加载到内存中。