ダウンロードサイズが大きい場合の対処方法
ダウンロード要求を行ったら、ダウンロードが完了したことを把握する必要がありますが、その方法については後ほど説明します。その前に、ダウンロードの進み具合をユーザーに知らせる方法を考えてみましょう。それには、DownloadProgressChangedイベントを使って、処理の進行状況を把握します。また、ダウンロードに時間がかかり過ぎている場合には、ユーザーがキャンセルしたくなることもありそうです。その機能を実現するには、CancelAsyncメソッドを使います。このセクションでは、この2つの処理について見ていきましょう。
処理の進行状況の把握
DownloadProgressChangedイベントでは、ダウンロード処理の進み具合を把握できます。ダウンロードが始まると、要求したコンテンツを取得し終わるまでの間は、DownloadProgressChangedイベントが繰り返し発生します。このイベントでは、DownloadProgressChangedEventArgsというパラメータがイベントハンドラに渡され、この中に、ダウンロードの進行状況に関する情報が入っています。DownloadProgressChangedEventArgs型で渡される情報の使用例をコード3に示します。
void webClient_DownloadProgressChanged(object sender,
DownloadProgressChangedEventArgs e)
{
StringBuilder sb = new StringBuilder();
sb.Append(e.BytesReceived + " of "); (1)
sb.Append(e.TotalBytesToReceive + " bytes received"); (2)
myTextBlock.Text = sb.ToString();
}
このコードは、DownloadProgressChangedイベントのイベントハンドラの例です。このコードでは、DownloadProgressChangedEventArgsパラメータを使って、ダウンロードの進み具合をユーザーに伝える文字列を組み立てています。このとき、BytesReceived(1)とTotalBytesToReceive(2)という2つのプロパティから進行状況の情報を取得しています。
ダウンロードするデータの全体のサイズを表すのがTotalBytesToReceiveプロパティです。要求したコンテンツの総バイト数をlong値で取得できます。また、ダウンロードが完了したデータのサイズを表すのがBytesReceivedプロパティです。ダウンロード済みのバイト数をlong値で取得できます。
BytesReceivedプロパティとTotalBytesToReceiveプロパティを使って進行状況を表示すれば、ダウンロードが正常に進んでいるのかというユーザーの不安を抑えるのに有効です。また、ダウンロードをキャンセルするかどうかをユーザーが決めるときの判断材料にもなります。
ダウンロード要求のキャンセル
ダウンロードの進行状況を表示すれば、処理の進み具合がわからないというユーザーの不安を解消できます。しかしそれでも、ダウンロードで長時間待たされるのはユーザーにとって苦痛です。ダウンロードを行わなくてもアプリケーションの動作に影響しないのなら、ユーザーがキャンセルできるようにしておくのが親切です。それにはCancelAsyncメソッドを使います。このメソッドの使用例をコード4に示します。
WebClient webClient = new WebClient();
protected void cancelButton_Click(object sender,
RoutedEventArgs e) (1)
{
if (webClient.IsBusy) (2)
{
webClient.CancelAsync(); (3)
}
}
このコードは、Cancelボタンがあると想定した場合のイベントハンドラです(1)。この中では、WebClientクラスのCancelAsyncメソッドを使って、ダウンロードをキャンセルしています(3)。このメソッドは、進行中のWeb要求を中止するときに呼び出します。この例では、IsBusyプロパティを使って、ダウンロードが進行中かどうかを明示的にチェックしています。このプロパティでは、処理が進行中かどうかがbool値で返ります(2)。実際には、このチェックは必須ではありませんが、これを使ってコードのパフォーマンスを向上させることができます。また、WebClientオブジェクトをインスタンス変数として宣言すると、コードのメンテナンス性が向上します。
上のコードから分かるように、CancelAsyncメソッドとIsBusyプロパティはWebClientクラスのメンバです。従って、WebClientクラスのインスタンスは、ダウンロード処理に関するクラスのメンバ変数として定義することをお勧めします。コード1とコード2ではそうしませんでしたが、クラスのメンバ変数にしておけば、ダウンロード要求のキャンセルを必要に応じて自在に処理でき、柔軟性が高まります。また、WebClientオブジェクトに対応するイベントハンドラの再利用も可能です。いずれにせよ、頭に入れておく必要があるのは、WebClientの1つのインスタンスで複数のダウンロード要求を同時に処理することはできないという点です。従って、ダウンロードを開始する前に、IsBusyプロパティを使ってチェックを行う方がよいかもしれません。さて、ここまでの説明では、ダウンロードの開始から完了までを取り上げました。次は、コンテンツの読み込み方についてです。
