.net - 为什么在关闭带有 WebBrowser 控件的窗体时出现 RaceOnRCWCleanup 错误?

标签 .net winforms webbrowser-control rcw

VS2008、.NET 2、VB.NET、XP ...

我有一个 Windows 窗体,带有一个 WebBrowser 控件和一个关闭按钮,它只执行 Me.Close 操作。 。表单的取消按钮设置为关闭按钮,以便我可以按 ESC 关闭表单。

我设置了DocumentText加载事件中的 WebBrowser 控件的属性,然后显示 HTML。

从 Visual Studio 运行应用程序,如果单击“关闭”按钮,表单将关闭且不会出现错误。

如果我按下 ESC 按钮,我会得到

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/

相关文章:

c# - 使用 Graphics.DrawImage() 绘制带透明度/Alpha channel 的图像

c# - Control.GetPreferredSize 方法的目的是什么?

c# - 属性网格 > 如何刷新主属性

c# - 如何检查窗体是否已经打开,如果是则关闭它?

c# - 如何用另一个 DocumentText 更新 DocumentText

.net - IHTMLSelectionObject.createRange() 抛出 UnauthorizedAccessException

.net - 如果未安装.NET,如何正常失败?

c# - 容错 XML 阅读器

c# - 我如何在没有打开图像 ui 的情况下在 C# 中的 Web 浏览器控件中插入图像?

c# - UdpClient 与 TcpClient