我对两个应用程序之间的交互有点问题。处理被阻止的消息循环
你可以用代码复制的问题是这样的:
using (Form1 frm = new Form1())
{
frm.ShowDialog();
}
Thread.Sleep(120000);
使用此代码,单独的应用程序,这是我们无法控制的,当我们的应用程序运行的代码Thread.Sleep
部分冻结。实际上,我们对发生的事情有了一个很好的想法,之前一直处于此bug的接收端:另一个应用程序有本地EnumWindows
方法的回调,它不检查是否使用IsWindowVisible本机方法查看窗口是否可见。然后,当它调用GetWindowText
或可能的其他功能时,它会挂起。
这个挂起的原因是它试图与我们(现在已关闭)的窗口进行通信,该窗口仍然有一个注册句柄,但没有响应发送到其队列的消息,因此主叫方只坐在那里无限期地(直到窗口完全死于我们的Thread.Sleep之后)。
这里是“贱民”的应用程序示例代码,我们不得不面对:
public bool RunTest()
{
return NativeMethods.EnumWindows(new NativeMethods.EnumWindowsProc(EnumWindowsCallback), IntPtr.Zero);
}
private bool EnumWindowsCallback(IntPtr windowHandle, IntPtr parameter)
{
NativeMethods.SendMessage(windowHandle, 0x000E, IntPtr.Zero, IntPtr.Zero);
return true;
}
如果您运行的第一个代码,请关闭它打开的窗口中,然后运行第二个代码块一个单独的进程,第二个(EnumWindows)进程将挂起。
我的问题是,我要解决这个问题,而不能只固定在悬挂应用程序的代码。我可以把窗户踢进一个单独的线程,但这看起来很笨拙,有点脆弱。有谁知道使用本地调用或其他更直接的方法清除此问题的方法?
真实的代码,这是执行以替代的Thread.Sleep,可能有一定的循环。尝试将Application.DoEvents添加到此循环中。 – 2013-03-13 18:50:55
此代码不包含任何循环 - 发布的代码触发错误,并且Form1是在Visual Studio中的空白Windows窗体项目中创建的默认窗体。 – 2013-03-13 19:06:14
表单*不应该*仍然有注册的句柄,因为'using'应该叫做'Dispose'。在睡眠之后是否有其他代码执行?或者一旦睡眠完成,程序是否会退出? – 2013-03-13 19:51:29