我有一个WinRT应用程序(8.0,而不是8.1,所以我不能使用Windows.Web.HttpClient)将大型文件上传到站点。我正在将System.Net.Http.HttpClient与Microsoft.AspNet.WebApi.Client nuget包中的System.Net.Http.Handlers.ProgressMessageHandler配合使用,以跟踪进度。
无论我上传的文件有多大,我似乎总是会一次调用一次HttpSendProgress事件,并且只有一次,进度为100%(和totalBytes == sendBytes)。但是,直到事件触发后的某个时候,文件才真正完成向网站的上传,具体取决于文件大小以及我是否限制了上传速度等。上传确实有效,但是进度报告没有用。
我使用了网络监视工具,可以看到在调用进度事件后(当我在断点处停止后让应用程序运行时),数据正在缓慢地传输-但是我只将事件引发了一次并且进度为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;
}
最佳答案
我建议将两个任务与ContinueWith
链接在一起,并使用TaskContinuationOptions.OnlyOnRanToCompletion
为ProgressMessageHandler
提供完全根据您的需要报告进度的机会。
希望这会有所帮助。
postResponse.ContinueWith(task =>
{
if (task.Result.IsSuccessStatusCode)
{
}
}, TaskContinuationOptions.OnlyOnRanToCompletion);