可能的线程/ COM / UI问题
-
04-07-2019 - |
题
我正在为IE(6+)编写工具栏。我使用了
中的各种样本条codeproject.com( http://www.codeproject.com/KB/dotnet /IE_toolbar.aspx ),并有一个工作的工具栏,注册取消注册等。我希望工具栏做的是突出显示html页面中的div,因为用户的鼠标移动到该div。到目前为止突出显示代码有效,但我想在工具栏上的标签中显示div的名称(如果存在)(随着鼠标移动等而改变)。
我无法为我的生活做到这一点,并试图调试它是一场噩梦。由于程序集托管在IE中,我怀疑我是通过尝试从没有创建该控件的线程更新标签上的文本而导致异常(在IE中),但是因为该异常发生在IE中,我看不到它。
解决方案是尝试使用Invoke以线程安全的方式更新控件吗?如果是这样的话?
以下是事件代码:
private void Explorer_MouseOverEvent(mshtml.IHTMLEventObj e)
{
mshtml.IHTMLDocument2 doc = this.Explorer.Document as IHTMLDocument2;
element = doc.elementFromPoint(e.clientX, e.clientY);
if (element.tagName.Equals("DIV", StringComparison.InvariantCultureIgnoreCase))
{
element.style.border = "thin solid blue;";
if (element.className != null)
{
UpdateToolstrip(element.className);
}
}
e.returnValue = false;
}
这是尝试线程安全更新工具栏:
delegate void UpdateToolstripDelegate(string text);
public void UpdateToolstrip(string text)
{
if (this.toolStripLabel1.InvokeRequired == false)
{
this.toolStripLabel1.Text = text;
}
else
{
this.Invoke(new UpdateToolstripDelegate(UpdateToolstrip), new object[] { text });
}
}
任何建议都非常感谢。
解决方案
我无法真正重现这个问题(为IE工具栏创建一个测试项目有点太多了),但你可以试试这个:
将以下例程添加到公共静态(扩展方法)类:
public static void Invoke(this Control control, MethodInvoker methodInvoker)
{
if (control.InvokeRequired)
control.Invoke(methodInvoker);
else
methodInvoker();
}
然后使用以下代码替换第一个块中类似代码的部分:
if (element.className != null)
{
this.Invoke(() => toolStripLabel1.Text = element.className);
}
这是避免UI应用程序中的线程安全问题的可靠方法。
不隶属于 StackOverflow