AutoResetEvent の動作がおかしい
Utilsクラスにコードがあります:
class Utils
{
public static AutoResetEvent FileDownloaded = new AutoResetEvent(false);
public static void DownloadFileAsync(string sourceUrl, string toPath)
{
var webClient = new WebClient();
var url = new Uri(sourceUrl);
FileDownloaded.Reset();
webClient.DownloadStringCompleted += (s, e) =>
{
Debug.WriteLine("DownloadStringAsinc completed");
if(e.Error != null || string.IsNullOrEmpty( e.Result))
{
//do retries
}
else
{
FileDownloaded.Set();
}
};
webClient.DownloadStringAsync(url);
}
}
そして、聞いているときのコードがあります:
public DoSomeWork()
{
Utils.DownloadFileAsync(iniUrl, localIni);
if(Utils.FileDownloaded.WaitOne(2222))
{
//....
}
else
//it goes here at initial run
}
それは次のように呼ばれました:
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += (object o, DoWorkEventArgs args) =>
{
DoSomeWork();
}
bw.RunWorkerAsync();
この場合、最初に WaitOne が呼び出されると、(タイムアウトしたように) すぐに false が返されます。2 回目は問題ありませんが、デバッグ出力に「DownloadStringAsinc が完了しました」というメッセージさえありません。メインスレッドから Utils.FileDownloaded.WaitOne(2222) を呼び出していたとき (正しくないことはわかっていますが、テストしているだけです)、想定どおりに機能しました。しかし、ブロックをスレッドに移動すると、この動作が現れました。また、後のブロックの「if」ステートメントの前に Thread.Sleep(200) を作成すると、すべて正常に動作します
追加する必要があります: Utils クラスのコードは、異なる場所から同時に呼び出されません。
私は次のように考えるかもしれません:「このアプリケーションの問題は解決しました」。しかし、それは私の頭では解決されていません。私は理解しなければなりません。