DownloadStringAsync とその他のイベント メソッドは、.NET 4.0 の TPL とうまく連携します (EAP と TPL を確認してください)。一般に、TPL は TaskCompletionSource を介したイベント非同期プログラミングをサポートします。Begin/EndXXX モデル (APM) は、Task.FromAsync メソッドによってサポートされます。詳細な説明TPL and Traditional .NET Asynchronous Programmingを見つけることができます。
ParallelExtensionExtrasライブラリには、適切なイベントが発生したときに完了するタスクを返す DownloadStringTask などの一連の WebClient 拡張メソッドがあります。
次のコードは、ダウンロードが完了すると完了するタスクを作成します。
public Task<string> DownloadStringTask(WebClient client,Uri uri)
{
var tcs = new TaskCompletionSource<string>();
client.DownloadStringCompleted += (o, a) => tcs.SetResult(a.Result);
client.DownloadStringAsync(uri);
return tcs.Task;
}
UI の更新に関しては、DownloadProgressChanged イベントを使用して簡単にフィードバックを提供できます。
using (var client = new WebClient())
{
client.DownloadProgressChanged += (o, a) => Console.WriteLine("{0}",a.ProgressPercentage);
var task = DownloadStringTask(client,new Uri("http://www.stackoverflow.com"));
var write=task.ContinueWith(t => Console.WriteLine("Got {0} chars", t.Result.Length));
write.Wait();
Console.ReadKey();
}
データ バインディングを使用して進行状況の値を進行状況バーに提供する場合は、進行状況の値のプロパティを更新するだけです。プログレス バーを直接更新する場合 (良い考えではありません)、プログレス バーのディスパッチャを使用して UI スレッドへの呼び出しをマーシャリングする必要があります。このような
void UpdateProgress(int percent)
{
if (progressBar1.CheckAccess())
progressBar1.Value = percent;
else
{
progressBar1.Dispatcher.Invoke(new Action(()=>UpdateProgress(percent)));
}
}
....
client.DownloadProgressChanged += (o, a) => UpdateProgress(a.ProgressPercentage);