0

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 クラスのコードは、異なる場所から同時に呼び出されません。

私は次のように考えるかもしれません:「このアプリケーションの問題は解決しました」。しかし、それは私の頭では解決されていません。私は理解しなければなりません。

4

0 に答える 0