2014-02-19 83 views
2

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

只需添加到我的问题 - 我发现用相同的症状上线(有些堆栈溢出)的几个职位,但往往建议是使用的HttpClient和progressmessagehandler(这是我想做),或者使用Windows.Web.HttpClient,由于工具兼容性等原因我暂时还不能这样做。尽管所有这些听起来都很相似,但它们似乎并不是我的问题的重复内容。 – Yort

+0

我还应该提到await client.PostAsync之后的代码,直到进度事件激发之后,以及出现数据实际上传时,才会恢复执行。因此,似乎该方法正在等待数据传输,但基于写入某种缓冲区来报告进度? – Yort

+0

请尝试使用[BackgroundUploader](http://msdn.microsoft.com/library/windows/apps/br207140)。它会返回一个叫做[UploadOperation(http://msdn.microsoft.com/en-US/library/windows/apps/windows.networking.backgroundtransfer.uploadoperation),这将允许您访问类似'Progress'事物的对象。 –

回答

0

我建议您链这两个任务与ContinueWith和使用TaskContinuationOptions.OnlyOnRanToCompletion给予ProgressMessageHandler报告完全按照你想要的进步的机会。

希望这可能有所帮助。

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