我正在制作一个将文件上传到Facebook的UWP应用程序,我正在使用自定义的HttpContent来将文件上传到4k块,以最大限度地减少大文件(> 100mb)的内存使用情况并报告进度.
我的自定义HttpContent UploadWithProgressHttpContent:
- class UploadWithProgressHttpContent : HttpContent
- {
- private readonly IProgress<OperationProgress> _progress;
- private readonly OperationProgress _data;
- private readonly Stream _file;
- private readonly int _bufferSize;
- private readonly CancellationToken _token;
- public UploadWithProgressHttpContent(
- IProgress<OperationProgress> progress,OperationProgress data,Stream file,int bufferSize,CancellationToken token)
- {
- _progress = progress;
- _data = data;
- _file = file;
- _bufferSize = bufferSize;
- _token = token;
- }
- protected override Task SerializeToStreamAsync(Stream stream,TransportContext context)
- {
- return CopyStreamWithProgress(_file,stream,_progress,_token,_data,_bufferSize);
- }
- public static async Task<Stream> CopyStreamWithProgress(
- Stream source,Stream destination,IProgress<OperationProgress> progress,CancellationToken token,OperationProgress progressData,int bufferSize
- )
- {
- int read,offset = 0;
- var buffer = new byte[bufferSize];
- using (source)
- {
- do
- {
- read = await source.ReadAsync(buffer,bufferSize,token);
- await destination.WriteAsync(buffer,read,token);
- offset += read;
- progressData.CurrentSize = offset;
- progress.Report(progressData);
- } while (read != 0);
- }
- return destination;
- }
- }
我使用(使用fiddler)的是,在上传开始之前,整个文件被放入内存(我的进度计在上传甚至启动之前达到了100%).
我确实尝试将TransferEncodingChunked设置为true,并设置文件内容长度,但仍然存在问题.
上传源在PCL内(如果重要).我正在使用最新版本的System.Net.Http.如果需要我正在使用它与MediaFire SDK中使用的完全相同的方式
感谢任何帮助.
- public async Task<T> Upload<T>(Stream fileStream,string fileName)
- {
- var handler = new HttpClientHandler();
- var cli = new HttpClient(handler);
- foreach (var header in Headers)
- {
- cli.DefaultRequestHeaders.Add(header.Key,header.Value);
- }
- var parameters = new MultipartFormDataContent();
- foreach (var parameter in Parameters)
- {
- parameters.Add(new StringContent(parameter.Value),parameter.Key);
- }
- if (fileStream != null)
- {
- var fileContent = new UploadWithProgressHttpContent(ProgressOperation,ProgressData,fileStream,_chunkBufferSize,Token,fileStream.Length);
- fileContent.Headers.ContentType = new MediaTypeHeaderValue(MimeTypeHelper.GetMimeType(fileName));
- fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue(StreamParamName);
- fileContent.Headers.ContentDisposition.FileName = fileName;
- fileContent.Headers.ContentLength = fileStream.Length;
- parameters.Add(fileContent,StreamParamName);
- }
- var req = new HttpRequestMessage(method,Path) { Content = parameters };
- if (fileStream != null)
- req.Headers.TransferEncodingChunked = true;
- var completionOption = HttpCompletionOption.ResponseContentRead;
- var resp = await cli.SendAsync(req,completionOption,Token).ConfigureAwait(false);
- return await DeserializeObject<T>(resp);
- }
解决方法
你有与量子力学相同的问题 – 观察观察变化的行为. Fiddler不支持请求流 – 请参阅
Fiddler makes HttpWebRequest/HttpClient behaviour unexpected
和
http://www.telerik.com/forums/is-it-possible-to-not-buffer-requests
Fiddler makes HttpWebRequest/HttpClient behaviour unexpected
和
http://www.telerik.com/forums/is-it-possible-to-not-buffer-requests
使用wireshark我可以看到大块.