ファイルをダウンロードし、ケースの進行状況が表示されます達成するために、.NET Frameworkで、最も簡単な方法は、使用することですのWebClientクラスを。購読DownloadProgressChangedライン上でイベントを。
しかし残念ながら、.NET標準には含まれていないWebクライアント。.NET標準では、ネットワークは、HTTPリクエストである必要があり、我々はより多くの使用する必要がHttpClientをします。また、UWPも持っている、ということに注意してくださいにHttpClientを使用がほとんどですが、しかし、名前空間が同じではありませんが、UWPが進行をダウンロードするためのサポートがあり、そこに手の込んだことはありません。
あなたは、ファイルをダウンロードしたい場合は、我々はHttpClientを使用しますGetByteArrayAsyncこの方法を。ダウンロードの進行状況を達成するために、それはそれを行う方法次第ですか?パッケージの諺に通り、誰もいません。ここでは、次のように定義された拡張メソッドを書きます:
公共の 静的な クラスHttpClientExtensions { 公共の 静的なタスク< バイト []> GetByteArrayAsync(この HttpClientをクライアント、ウリrequestUri、IProgress <HttpDownloadProgress> 進展、CancellationToken cancellationToken) { スロー 新)(NotImplementedExceptionを。 } }
次のようにHttpDownloadProgress構造(理由を言う私の下にクラスを使用しない)私自身の定義、どれ:
パブリック 構造体HttpDownloadProgress { 公共 ULONGは、bytesreceived { 取得します。セット; } 公共 ULONG?TotalBytesToReceive { 取得します。セット; } }
バイト数は、bytesreceived代表がダウンロードされている、TotalBytesToReceiveはHTTP応答ヘッダは、必ずしも長さ(コンテンツ長)を返さないので、空であることがここで設定され、ダウンロードされるべきバイトの数を表します。
我々はコンテンツ長にHTTPレスポンスヘッダから取得し、HttpClientをGetByteArrayAsyncと達成するための方法はありませんを所有する必要があるため、我々はこの方法GetAsyncに移行する必要があります。GetAsyncこのメソッドは、オーバーロードされたhttps://docs.microsoft.com/zh-cn/dotnet/api/system.net.http.httpclient.getasync#System_Net_Http_HttpClient_GetAsync_System_Uri_System_Net_Http_HttpCompletionOption_System_Threading_CancellationToken_ 2番目の引数が何であるかに代わって、列挙ですとき、私は応答を得ることができます。需要によると、私たちはここにHttpCompletionOption.ResponseHeadersRead、これを使用する必要があります。
またHttpClientをソースコードは、ビューのGithubの点で得ることができます。https://github.com/dotnet/corefx/blob/d69d441dfb0710c2a34155c7c4745db357b14c96/src/System.Net.Http/src/System/Net/Http/HttpClient.cs我々は実現GetByteArrayAsyncを参照することができます。
反射に、私たちは次のようなコードを書くことができます。
パブリック 静的 クラスHttpClientExtensions { 民間 のconst int型たBufferSize = 8192 ; 公共の 静的な 非同期タスク< バイト []> GetByteArrayAsync(この HttpClientをクライアント、ウリrequestUri、IProgress <HttpDownloadProgress> 進展、CancellationToken cancellationToken) { 場合(クライアント== nullの) { スロー 新しい例外ArgumentNullException(がNameOf(クライアント)); } 使用(VARの responseMessageを= 待ちますclient.GetAsync(requestUri、HttpCompletionOption.ResponseHeadersRead、cancellationToken).ConfigureAwait(偽)) { responseMessage.EnsureSuccessStatusCode()。 VARの内容= responseMessage.Content。 もし(コンテンツ== NULL ) { 戻り Array.Empty < バイト > (); } VARのヘッダー= content.Headers。 VARん。ContentLength = headers.ContentLength。 使用して(VaRの responseStreamの=を待ちます。content.ReadAsStreamAsync()ConfigureAwait(偽)) { VARのバッファ= 新しい バイト[たBufferSize]。 int型bytesRead; するvarバイト= 新しいリスト< バイト > (); VAR downloadProgress = 新しいHttpDownloadProgress(); もし(contentLength.HasValue) { downloadProgress.TotalBytesToReceive =(ULONG )contentLength.Value。 } 進行?.Report(downloadProgress)。 一方、((bytesRead =を待つ responseStream.ReadAsync(バッファ、0、たBufferSize、cancellationToken).ConfigureAwait(偽))> 0 ) { bytes.AddRange(buffer.Take(bytesReadを)); downloadProgress.BytesReceived + =(ULONG )bytesRead。 進歩?.Report(downloadProgress)。 } を返す)(bytes.ToArrayします。 } } } }
ここで私は、もちろん、これは良いでしょう、あなたはこの小さな値の調整を置くことができるものを教えてください、ダウンロードの進捗度読み取りレポートあたり8キロバイトに相当8192バイト(8 KB)にバッファを設定しますが、相対的なパフォーマンスになりますいくつかの後方。しかし、またHttpDownloadProgressクラス(またはGC大きな圧力下になります)には適していませんが、比較的高い周波数のレポートですので、ので。
今、私はデモレンダリングを所有します: