昨夜、勉強になったので備忘録に。 PowerShellではしょっちゅう.NETを利用します。
その中でも、System.Net.WebClientは、サイトのHTMLを取得する際に便利なので利用しがちです。 DownloadFileとDownloadFileAsyncの利用時の違いがイマイチピンときて無かったのが少し解消したので備忘録に。
DownloadFile利用例
まずは利用例から。
$URI = "http://example.net/" $savefile = "D:\example\exmaple" $ext = ".html" $syncWebClient = New-Object -TypeName System.Net.WebClient 10001..20000 | %{ $syncWebClient.DownloadFile($URI,$($savefile + $_ + $ext)) }
.NETライクで、パイプを噛ませてないので寂しいのですが。
これで、10000回、対象サイトのHTMLを取得して、自身のD:\exampleにダウンロード、ファイル名に何回目のファイルかをつけてくれます。
$()は部分式、良く使いますね。
DownloadFileは、同期方式です。
同期の場合、System.Net.WebClientで1つずつの処理を終わるまで次のDownloadFileメソッドを実行しないので生成は1回でいいとなります。
DownloadFileAsync利用例
まずは利用例から。
$URI = "http://example.net/" $savefile = "D:\example\exmaple" $ext = ".html" 1..10000 | %{ $asyncWebClient = New-Object -TypeName System.Net.WebClient $asyncWebClient.DownloadFileAsync($URI,$($savefile + $_ + $ext)) }
先ほどとの違いは、New-ObjectでのSystem.Net.WebClientインスタンス生成が都度行われている点です。 これは、DownloadAsyncが実行後すぐにComplete扱いになるため、接続分のインスタンスを生成します。
仮に、DownlaodFileと同様に以下のように書くと、
$URI = "http://example.net/" $savefile = "D:\example\exmaple" $ext = ".html" $asyncWebClient = New-Object -TypeName System.Net.WebClient 1..10000 | %{ $asyncWebClient.DownloadFileAsync($URI,$($savefile + $_ + $ext)) }
非同期の場合は、System.Net.WebClientを随時生成しないと以下のエラーが2つめのダウンロード以降出てきます。
"2" 個の引数を指定して "DownloadFileAsync" を呼び出し中に例外が発生しました: "WebClient は同時 I/O 操作をサポートしません。"
実行速度
それはもう、DownloadFileAsyncの方が早いです。
- DownloadFileAsyncなら、必要数のインスタンス生成分だけの時間だけロック。ダウンロードは非同期
- DownlaodFileだと、インスタンスの生成は一個ですが、ファイルダウンロード中ロック
結果は、一目瞭然ですね。
- DownloadFileAsyncの場合、現在ダウンロード中かどうかの判断をしたほうがいい
- CancelAsyncメソッドを使用すると、未完了の非同期操作をキャンセルできる