DownloadStringCompletedイベントでこのエラーを取得するにはどうすればよいですか?終わったじゃないですか。これを起動できる別のイベントはありますか?
このエラーが発生することは非常にまれですが、たまにWP7電話で発生することがあります。何度も起動するWebクライアントがあり、完了したイベントからもう一度起動します。まだ古い接続が開いているため、これが発生していますか?これを100%防ぐ方法はありますか?
スレッドがそれ自体の上を歩く可能性があるかどうかを確認しましたが、完了したイベント内からのみ発生します。
Completeイベントが発生したときに、クライアントがisBusyではないことをどのように確認できますか? 1つの提案は、クライアントがビジー状態のときにスレッドスリープを追加することです。
いくつかの擬似コード。
var client = new WebClient("URL 1");
client.CompletedEvent += CompletedEvent;
client.downloadasync();
void CompletedEvent(){
Dosomestuff;
client.downloadasync(); //This is where we break.
}
WebClientは単一の操作のみをサポートし、複数のファイルをダウンロードすることはできません。コードは表示していませんが、古いリクエストが完了する前に、どういうわけか新しいリクエストを発行していると思います。私の賭けはWebClient.IsBusy
は、別のフェッチを実行しようとしたときにtrueになります。
次のスレッドを参照してください。
wb.DownloadFileAsync throw "WebClientは同時I/O操作をサポートしていません。"例外
唯一の答えは、完了したイベントのスコープ内で新しいWebクライアントを作成することです。 webclientは読み取り専用であるため、これをnewに設定することはできません。新しいクライアントを作成することが唯一のソリューションです。これにより、古いクライアントをバックグラウンドで完了することができます。古いインスタンスを再利用するのではなく、新しいインスタンスを作成するため、これはメモリにわずかに影響します。ただし、スコープが正しく設定されていれば、ガベージコレクターはクリーンな状態を保つ必要があります。
WebClientを使用する代わりに、HttpClientを使用して並列HTTP呼び出しを実行します。以下のコードは、ファイルをダウンロードする方法を示しています。
HttpClient httpClient = new HttpClient();
var documentList=_documentManager.GetAllDocuments();
documentList.AsParallel().ForAll(doc =>
{
var responseResult= httpClient.GetAsync(doc.FileURLPath);
using (var memStream = responseResult.Result.Content.ReadAsStreamAsync().Result)
{
using (var fileStream =File.Create($"{filePath}\\{doc.FileName}"))
{
memStream.CopyTo(fileStream);
}
}
});
私が見つけた解決策は、複数のWebClientオブジェクトを使用して、疑似コードの例を変更することです。試す
var client = new WebClient("URL 1");
client.CompletedEvent += CompletedEvent;
client.downloadasync();
void CompletedEvent(){
Dosomestuff;
var client2 = new WebClient();
client2.downloadasync();
}