How to implement progress reporting for Portable HttpClient

后端 未结 2 1115
闹比i
闹比i 2020-12-01 10:21

I\'m writing a library with intentions to use it in desktop (.Net 4.0 and up), phone (WP 7.5 and up) and Windows Store (Windows 8 and up) apps.

The library has the c

相关标签:
2条回答
  • 2020-12-01 10:22

    I wrote the following code to implement progress reporting. The code supports all the platforms I wanted; however, you need to reference the following NuGet packages:

    • Microsoft.Net.Http
    • Microsoft.Bcl.Async

    Here is the code:

    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);
        }
    }
    

    The using it is as simple as:

    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);
    
    0 讨论(0)
  • 2020-12-01 10:48

    You can specify HttpCompletionOption.ResponseHeadersRead and then get the stream and report progress while you read from the stream. See this similar question.

    0 讨论(0)
提交回复
热议问题