5

ブロックを解除していないように見える使用している ManualResetEvent について少し混乱しています。なぜこれが当てはまるのか誰にも分かりますか?

私が持っているシナリオは、これらの線に沿ったものです。実際の状況は非常に複雑で、問題を再現するために投稿するのが妥当なコードのセクションを分離することができませんでした。

EDIT
以下のコード例を更新しました。これはさまざまなダイアログで実行され、そのうちの 1 つが this.mre.WaitOne(); にヒットすることに気付きました。次に、「サーバービジー」ダイアログが表示され、「切り替え」または「再試行」を押す必要があります。これにより、コードが WaitOne() 呼び出しを通過し、すべてが機能します。それがどのように関連しているかはわかりませんが、明らかに重要なものです。

public class A
{
 ManualResetEvent mre;

 public void Start(ThreadClass tc)
 {
    this.mre = new ManualResetEvent(false);
    tc.Begin();

    WebClient wc = new WebClient();
    // progress events are pumped to the ThreadClass which then update the Form2.
    wc.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(wc_DownloadFileCompleted);

    wc.DownloadFileAsync("Src", "Tgt");
    this.mre.WaitOne();
 }

 void void wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
 {
    try
    {
     // Do Stuff
    }
    finally
    {
      this.mre.Set();
    }
 }
}

public class ThreadClass
{
   Begin()
   {
      Thread t = new Thread(new ThreadStart(DoWork));
      t.Start();
   }

   private void DoWork()
   {
     Form f = new Form2();
     f.ShowDialog();

     // Sits waiting on another ResetEvent to determine when to close the thread.
   }
}
4

4 に答える 4

4

Webclient は呼び出し元と同じスレッドで実行されるため、そのスレッドは WaitOne でブロックされ、実際には新しいスレッドは作成されません。

コードを BackgroundWorker に移動するか、単にブロックせずに DownloadComplete イベントが発生するのを待ちます。

于 2009-07-30T10:20:33.667 に答える
3

設定しているMREが実際に待機しているMREと同じであることを確認してください。これは単純化された例だとおっしゃっていますが、実際のコードで2つの異なるリセットイベントを作成している可能性はありますか?それはかなり明らかに物事を壊すでしょう:)

于 2009-07-30T10:35:36.367 に答える
2

私はあなたのコードを少し修正しました。問題は、MRE オブジェクトを DownloadFileAsync メソッドのユーザー状態パラメーターとして渡す必要があることでした。

public class A 
{  
 public void Start(ThreadClass tc) 
 { 
    ManualResetEvent mre = new ManualResetEvent(false);
    WebClient wc = new WebClient(); 
    // progress events are pumped to the ThreadClass which then update the Form2. 
    wc.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(wc_DownloadFileCompleted); 

    wc.DownloadFileAsync("Src", "Tgt", mre); 
    mre.WaitOne();
    mre.Close();
 } 

 void void wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) 
 { 
    try 
    { 
     // Do Stuff 
    } 
    finally 
    { 
      (e.UserState as ManualResetEvent).Set();
    } 
 } 
} 
于 2010-06-10T14:41:51.080 に答える
1

とにかくブロックしたい場合は、wc.DownloadFileAsyncの代わりにwc.DownloadFileを使用しないでください..

于 2009-07-30T10:23:03.537 に答える