System.Net.Http.Handlers.ProgressMessageHandler立即返回100%

时间:2014-02-19 10:42:08

标签: c# upload windows-runtime httpclient progress

我有一个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 == 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;
}

1 个答案:

答案 0 :(得分:0)

我建议您使用ContinueWith将这两项任务联系起来,并使用TaskContinuationOptions.OnlyOnRanToCompletionProgressMessageHandler有机会完全按照您的意愿报告进度。

希望这可能会有所帮助。

postResponse.ContinueWith(task =>
     {
         if (task.Result.IsSuccessStatusCode)
         { 
         }
     }, TaskContinuationOptions.OnlyOnRanToCompletion);