Come implementare la segnalazione dei progressi per Portable HttpClient

Sto scrivendo una libreria con l’intenzione di usarla su desktop (.Net 4.0 e versioni successive), telefono (WP 7.5 e versioni successive) e Windows Store (Windows 8 e versioni successive).

La libreria ha la capacità di scaricare file da Internet utilizzando la libreria HttpClient portatile e di segnalare lo stato di avanzamento del download.

Cerco da queste parti e dal resto di Internet per documentazioni e esempi di codice / linee guida su come implementare la segnalazione dei progressi, e questa ricerca mi ha portato da nessuna parte.

Qualcuno ha un articolo, una documentazione, una linea guida, un campione di codice o qualsiasi altra cosa per aiutarmi a raggiungere questo objective?

Ho scritto il seguente codice per implementare la segnalazione dei progressi. Il codice supporta tutte le piattaforms che volevo; tuttavia, è necessario fare riferimento ai seguenti pacchetti NuGet:

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

Ecco il codice:

public async Task DownloadFileAsync(string url, IProgress 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); } } 

L’utilizzo è semplice come:

 var progress = new Microsoft.Progress(); 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); 

È ansible specificare HttpCompletionOption.ResponseHeadersRead e quindi ottenere lo stream e segnalare lo stato di avanzamento mentre si legge dallo stream. Vedi questa domanda simile .