VS2008、.NET 2、VB.NET、XP ...
我有一个 Windows 窗体,带有一个 WebBrowser 控件和一个关闭按钮,它只执行 Me.Close
操作。 。表单的取消按钮设置为关闭按钮,以便我可以按 ESC 关闭表单。
我设置了DocumentText
加载事件中的 WebBrowser 控件的属性,然后显示 HTML。
从 Visual Studio 运行应用程序,如果单击“关闭”按钮,表单将关闭且不会出现错误。
如果我按下 ESC 按钮,我会得到 p>
RaceOnRCWCleanup was detected Message: An attempt has been made to free an RCW that is in use. The RCW is in use on the active thread or another thread. Attempting to free an in-use RCW can cause corruption or data loss.
如果我在 VS 之外运行该应用程序,则不会出现错误。
有什么想法a)为什么会出现错误,b)如何防止或抑制它?
提前非常感谢。
最佳答案
这不是错误,而是警告。由托管调试助手 (MDA) 生成,MDA 是托管代码调试器的扩展,它认为它发现代码中出现问题。鞋子合脚。您使用的是RCW,WebBrowser是COM控件。你正在消灭 RCW,你正在关闭你的表格。 MDA 介入是因为它认为它看到了正在使用的 Web 浏览器,并且在请求完成之前就被终止了。通常,只有当您在代码中使用线程时,这才有意义。
你是吗?如果没有,请不要为此失眠。 COM 使用引用计数,但因无法解析循环引用而臭名昭著。
<小时/>好的,我得到了这个的重现,通过评论启用。是的,这是由表单的 CancelButton 属性或按钮的 DialogResult 属性触发的。当 WB 获得焦点时会发生这种情况,它会看到按下 Escape 键。 ActiveX 管道的一部分是告诉容器有关它的信息,以便它可以响应应该产生副作用的击键。快捷键,Tab,Enter。和逃脱。如果该按钮随后关闭窗体,则调试器会看到 WB 被释放,同时堆栈上存在来自 RCW 代码的事件堆栈帧。危险在于,当 COM 组件被释放后,调用的代码返回时,这可能会导致崩溃,这种情况并不罕见。
看到这种崩溃的可能性很小,但我可以想象,当终结器线程在按钮的 Click 事件返回之前运行时,这可能会发生崩溃。 MDA 和潜在崩溃的解决方法是延迟关闭表单,直到 ActiveX 代码停止运行。使用 Control.BeginInvoke() 优雅地完成。像这样:
private void CancelButton_Click(object sender, EventArgs e) {
this.BeginInvoke((MethodInvoker)delegate { this.Close(); });
}
关于.net - 为什么在关闭带有 WebBrowser 控件的窗体时出现 RaceOnRCWCleanup 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1874496/