C# ManualResetEvent WaitOne 未解除阻塞
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1205674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ManualResetEvent WaitOne not unblocking
提问by Ian
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?
我对我正在使用的 ManualResetEvent 似乎没有解除阻塞感到有些困惑。有谁知道为什么会这样?
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.
编辑
我已经更新了下面的代码示例。这是在许多不同的对话框中执行的,我注意到其中一个点击了 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.
}
}
采纳答案by Ray Hayes
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 事件。
回答by Zyphrax
Why not use wc.DownloadFile instead of wc.DownloadFileAsync if you want it to block anyways..
如果您希望它无论如何都阻止,为什么不使用 wc.DownloadFile 而不是 wc.DownloadFileAsync ..
回答by Jon Skeet
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 realcode you're creating two different reset events? That would fairly obviously break things :)
检查您设置的 MRE 实际上是否与您正在等待的 MRE 相同。你说这是一个简化的例子——在真实的代码中你是否有可能创建两个不同的重置事件?那很明显会破坏事情:)
回答by Dimitar Paskov
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();
}
}
}