我有一个WinRT应用程序(8.0,不是8.1,所以我不能使用Windows.Web.HttpClient)在哪里上传大文件到网站。我使用System.Net.Http.HttpClient从Microsoft.AspNet.WebApi.Client NuGet包用于跟踪进度的目的,System.Net.Http.Handlers.ProgressMessageHandler。System.Net.Http.Handlers.ProgressMessageHandler立即返回100%
不管我上传的文件有多大,我似乎总是调用一次HttpSendProgress事件,并且只有一次,100%进度(和totalBytes == sentBytes)。然而,该文件实际上并没有完成上传到该网站,直到事件发生后的一段时间,这取决于文件大小以及是否限制了上传速度等。上传确实有效,但进度报告是无用的。
我使用了一个网络监控工具,可以在调用进度事件后(当我让应用程序在停止点后停止运行)后看到缓慢传输的数据 - 但我只收到了一次事件上传完成前100%进展。
我认为HttpClient正在写入某种缓冲区,发生的速度比实际的上传速度快得多,但我无法弄清楚如何更改/防止该问题,或者ProgressMessageHandler类的要点是什么它总是以这种方式工作。
目前我使用的代码如下所示:
public static async Task<string> UploadDataAsync(string uploadUrl, byte[] data, string contentTypeHeader, string oauthHeader, Action<long, long?> progressCallback)
{
var ph = new System.Net.Http.Handlers.ProgressMessageHandler();
if (progressCallback != null)
{
ph.HttpSendProgress += (sender, args) =>
{
progressCallback(args.BytesTransferred, args.TotalBytes);
};
}
var client = HttpClientFactory.Create(ph);
client.Timeout = new TimeSpan(0, 20, 0);
if (!String.IsNullOrEmpty(oauthHeader))
client.DefaultRequestHeaders.Add("Authorization", oauthHeader);
var content = new ByteArrayContent(data);
content.Headers.TryAddWithoutValidation("Content-Type", contentTypeHeader);
var postResponse = await client.PostAsync(new Uri(uploadUrl), content);
var result = await postResponse.Content.ReadAsStringAsync();
if (!postResponse.IsSuccessStatusCode)
{
throw new OAuthException(result);
}
return result;
}
只需添加到我的问题 - 我发现用相同的症状上线(有些堆栈溢出)的几个职位,但往往建议是使用的HttpClient和progressmessagehandler(这是我想做),或者使用Windows.Web.HttpClient,由于工具兼容性等原因我暂时还不能这样做。尽管所有这些听起来都很相似,但它们似乎并不是我的问题的重复内容。 – Yort
我还应该提到await client.PostAsync之后的代码,直到进度事件激发之后,以及出现数据实际上传时,才会恢复执行。因此,似乎该方法正在等待数据传输,但基于写入某种缓冲区来报告进度? – Yort
请尝试使用[BackgroundUploader](http://msdn.microsoft.com/library/windows/apps/br207140)。它会返回一个叫做[UploadOperation(http://msdn.microsoft.com/en-US/library/windows/apps/windows.networking.backgroundtransfer.uploadoperation),这将允许您访问类似'Progress'事物的对象。 –