如何计算与HttpClient的PostAsync进展? [英] How can I calculate progress with HttpClient PostAsync?
问题描述
在我的Windows Store应用(C#)我需要上传 MultipartFormDataContent
(一些字符串的内容和一些文件),以服务器和响应得到一个巨大的文件。这个问题 - 我不能使用 BackgroundDownloaders
为。我只能用一个请求为
In my Windows Store App (c#) I need to upload MultipartFormDataContent
(some strings content and some files) to server and get a huge file at response. The problem - I can't use BackgroundDownloaders
for that. I can only use one request for that.
我用 HttpClient.PostAsync
方法:
using (var client = new HttpClient(httpClientHandler))
{
using (var content = new MultipartFormDataContent())
{
content.Add(...); // prepare all strings and files content
try
{
using (var response = await client.PostAsync(url, content))
{
if (response.StatusCode == HttpStatusCode.OK)
{
var inputBytes = await response.Content.ReadAsByteArrayAsync();
// some operations with inputBytes
}
......
}
}
}
}
我的问题是:我如何计算这个操作的进展如何?
My question is: How can I calculate progress of this operation?
注意: - Windows 8中,我不能使用 Windows.Web.Http.HttpClient <
我的目标/ code>(最低支持的客户端Windows 8.1)。只有 System.Net.Http.HttpClient
Note: My target - Windows 8. And I can't use Windows.Web.Http.HttpClient
(Minimum supported client Windows 8.1). Only System.Net.Http.HttpClient
推荐答案
我面临同样的问题。我通过实现自定义的固定它 HttpContent
。我使用这个对象来跟踪上传进度百分比,你可以添加一个事件来,听它。你应该定义 SerializeToStreamAsync
法
I faced same issue. I fixed it by implementing custom HttpContent
. I use this object to track percentage of upload progress, you can add an event to and listen it. You should customize SerializeToStreamAsync
method.
internal class ProgressableStreamContent : HttpContent
{
private const int defaultBufferSize = 4096;
private Stream content;
private int bufferSize;
private bool contentConsumed;
private Download downloader;
public ProgressableStreamContent(Stream content, Download downloader) : this(content, defaultBufferSize, downloader) {}
public ProgressableStreamContent(Stream content, int bufferSize, Download downloader)
{
if(content == null)
{
throw new ArgumentNullException("content");
}
if(bufferSize <= 0)
{
throw new ArgumentOutOfRangeException("bufferSize");
}
this.content = content;
this.bufferSize = bufferSize;
this.downloader = downloader;
}
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
Contract.Assert(stream != null);
PrepareContent();
return Task.Run(() =>
{
var buffer = new Byte[this.bufferSize];
var size = content.Length;
var uploaded = 0;
downloader.ChangeState(DownloadState.PendingUpload);
using(content) while(true)
{
var length = content.Read(buffer, 0, buffer.Length);
if(length <= 0) break;
downloader.Uploaded = uploaded += length;
stream.Write(buffer, 0, length);
downloader.ChangeState(DownloadState.Uploading);
}
downloader.ChangeState(DownloadState.PendingResponse);
});
}
protected override bool TryComputeLength(out long length)
{
length = content.Length;
return true;
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
content.Dispose();
}
base.Dispose(disposing);
}
private void PrepareContent()
{
if(contentConsumed)
{
// If the content needs to be written to a target stream a 2nd time, then the stream must support
// seeking (e.g. a FileStream), otherwise the stream can't be copied a second time to a target
// stream (e.g. a NetworkStream).
if(content.CanSeek)
{
content.Position = 0;
}
else
{
throw new InvalidOperationException("SR.net_http_content_stream_already_read");
}
}
contentConsumed = true;
}
}
这篇关于如何计算与HttpClient的PostAsync进展?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!