ManualResetEvent WaitOne 未解锁
我对我正在使用的 ManualResetEvent 有点困惑,它似乎没有解锁。 有谁知道为什么会出现这种情况?
我得到的场景就是这样的。 真实的情况相当复杂,我还没有成功地隔离出一段可以合理发布来重现问题的代码。
编辑
我更新了下面的代码示例。 这是在许多不同的对话框中执行的,我注意到其中一个对话框点击了 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.
}
}
I'm a little confused over a ManualResetEvent that I'm using which doesn't appear to be unblocking. 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(); 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. 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.
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您希望无论如何都阻止它,为什么不使用 wc.DownloadFile 而不是 wc.DownloadFileAsync..
Why not use wc.DownloadFile instead of wc.DownloadFileAsync if you want it to block anyways..
我对你的代码做了一些修改,现在它会按预期工作。 问题是您应该将 MRE 对象作为 DownloadFileAsync 方法的用户状态参数传递:
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 是否实际上与您正在等待的 MRE 相同。 您说这是一个简化的示例 - 是否有可能在真实代码中创建两个不同的重置事件? 这显然会破坏事情:)
Check that the MRE you're setting is actually the same MRE you're waiting on. 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 :)
Webclient 与您的调用者在同一线程中运行,因此该线程在 WaitOne 处被阻塞,它实际上并没有为您创建新线程。
将您的代码移至BackgroundWorker 中,或者简单地说,不要阻塞,而是等待引发DownloadComplete 事件。
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.
Move your code into a BackgroundWorker or simply, don't block but wait for the DownloadComplete event to be raised.