考えられるスレッディング/ COM / UIの問題
-
04-07-2019 - |
質問
IE(6+)のツールバーを書いています。
のさまざまなサンプルバーを使用しましたcodeproject.com( http://www.codeproject.com/KB/dotnet /IE_toolbar.aspx )、機能するツールバー、登録解除などを登録します。ツールバーで実行したいのは、ユーザーのマウスがそのdiv上を移動するときにhtmlページ内の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(拡張メソッド)クラスに追加します:
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