首页 文章

如何实现Portable HttpClient的进度报告

提问于
浏览
6

我正在编写一个图书馆,意图在桌面(.Net 4.0及更高版本),手机(WP 7.5及以上版本)和Windows Store(Windows 8及更高版本)应用程序中使用它 .

该库具有使用Portable HttpClient库从Internet下载文件的功能,并报告下载的进度 .

我在这里和互联网的其余部分搜索有关如何实施进度报告的文档和代码示例/指南,这次搜索让我无处可去 .

有没有人有文章,文档,指南,代码示例或其他什么来帮助我实现这一目标?

2 回答

  • 1

    我编写了以下代码来实现进度报告 . 代码支持我想要的所有平台;但是,您需要引用以下NuGet包:

    • Microsoft.Net.Http

    • Microsoft.Bcl.Async

    这是代码:

    public async Task DownloadFileAsync(string url, IProgress<double> progress, CancellationToken token)
    {
        var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
    
        if (!response.IsSuccessStatusCode)
        {
            throw new Exception(string.Format("The request returned with HTTP status code {0}", response.StatusCode));
        }
    
        var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;
        var canReportProgress = total != -1 && progress != null;
    
        using (var stream = await response.Content.ReadAsStreamAsync())
        {
            var totalRead = 0L;
            var buffer = new byte[4096];
            var isMoreToRead = true;
    
            do
            {
                token.ThrowIfCancellationRequested();
    
                var read = await stream.ReadAsync(buffer, 0, buffer.Length, token);
    
                if (read == 0)
                {
                    isMoreToRead = false;
                }
                else
                {
                    var data = new byte[read];
                    buffer.ToList().CopyTo(0, data, 0, read);
    
                    // TODO: put here the code to write the file to disk
    
                    totalRead += read;
    
                    if (canReportProgress)
                    {
                        progress.Report((totalRead * 1d) / (total * 1d) * 100);
                    }
                }
            } while (isMoreToRead);
        }
    }
    

    使用它很简单:

    var progress = new Microsoft.Progress<double>();
    progress.ProgressChanged += (sender, value) => System.Console.Write("\r%{0:N0}", value);
    
    var cancellationToken = new CancellationTokenSource();
    
    await DownloadFileAsync("http://www.dotpdn.com/files/Paint.NET.3.5.11.Install.zip", progress, cancellationToken.Token);
    
  • 18

    您可以指定HttpCompletionOption.ResponseHeadersRead,然后在从流中读取时获取流并报告进度 . 见this similar question .

相关问题