简体   繁体   English

ManualResetEvent WaitOne没有解锁

[英]ManualResetEvent WaitOne not unblocking

I'm a little confused over a ManualResetEvent that I'm using which doesn't appear to be unblocking. 我对我正在使用的看起来没有解锁的ManualResetEvent感到有点困惑。 Anyone know why this might be the case? 任何人都知道为什么会这样吗?

The scenario I've got is something along these lines. 我得到的情景是这样的。 The real situation is quite complicated and I've not managed to isolate a section of code that's reasonable to post to reproduce the issue. 真实情况非常复杂,我没有设法隔离一段合理的代码来重现问题。

EDIT 编辑
I've updated the code example below. 我已经更新了下面的代码示例。 This is execute in a number of different dialogs and I have noticed that one of them hits the this.mre.WaitOne(); 这是在许多不同的对话框中执行的,我注意到其中一个命中了this.mre.WaitOne(); Then what happens is I get a "Server Busy" dialog, where I need to press 'switch to' or 'retry', which will then allow my code to step passed the WaitOne() call and all will work. 然后发生的是我得到一个“服务器忙”对话框,我需要按“切换到”或“重试”,这将允许我的代码步骤通过WaitOne()调用,一切都会工作。 I'm not sure how its relevant, but obviously its of some important. 我不确定它的相关性,但显然它有些重要。

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.
   }
}

Webclient runs in the same thread as your caller, so that thread is blocked at the WaitOne, it doesn't actually create a new thread for you. Webclient在与调用者相同的线程中运行,因此该线程在WaitOne处被阻塞,它实际上并不为您创建新线程。

Move your code into a BackgroundWorker or simply, don't block but wait for the DownloadComplete event to be raised. 将代码移动到BackgroundWorker中,或者只是,不要阻止,而是等待引发DownloadComplete事件。

Check that the MRE you're setting is actually the same MRE you're waiting on. 检查您设置的MRE是否与您正在等待的MRE相同。 You say this is a simplified example - is it possible that in the real code you're creating two different reset events? 你说这是一个简化的例子 - 你可能在实际代码中创建了两个不同的重置事件吗? That would fairly obviously break things :) 这显然会破坏事情:)

I have modified your code a bit and it will work as supposed to now. 我已经修改了一下你的代码,它会像现在一样工作。 The problem was that you should have passed the MRE object as the user state parameter of the DownloadFileAsync method: 问题是您应该已将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();
    } 
 } 
} 

如果你想要阻止它,为什么不使用wc.DownloadFile而不是wc.DownloadFileAsync ..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM