IE工具栏中实例的静态引用

时间:2011-05-13 14:46:32

标签: c# internet-explorer com singleton instance

我有一个有趣的问题,一个COM组件被编写为IE中的工具栏。基本上,如果你在IE中一次打开几个标签,COM对象的各个实例都会被扭曲。跟我在一起。

假设我通过右键单击几个不同的链接并在新选项卡中打开它们,一次打开五个浏览器选项卡。现在,我的工具栏功能包括在网页中选择文本,然后单击按钮将该文本复制到工具栏中。所以我们在标签3中这样做。我们选择文本并单击按钮,没有任何内容。但是,如果我们在选项卡2中选择文本,然后返回选项卡3并单击按钮,我们将在选项卡2中选择文本。因此...选项卡3中的工具栏从选项卡2中获取内容。不好。

我已将此问题追溯到COM对象(工具栏)中的静态引用。

[ComVisible(true), Guid("2CC75392-1182-470D-BECC-EFA33E629AB8")]
[CLSCompliant(false)]
public sealed class Toolbar : ADXIEToolbar
{

    public static Toolbar Instance;

    public Toolbar()
    {
        Instance = this;

        InitializeComponent();

    }

   ...other code...
}

请注意,每个IE选项卡只存在一个工具栏实例。

这个引用没有被正确分配,几乎就像它不是线程安全的(它不是)但不是域安全的东西。它有时会引用另一个实例。与其他静态字段甚至线程安全的单例相同。我不明白。

另请注意,如果我将对此工具栏的引用(在InitializeComponent内)传递给控件,​​我会遇到同样的问题。

this.publicationDateCb.Toolbar = this;

此引用有时会指向不同的选项卡。

如果我使用纯粹基于订阅的模型,并且工具栏作为裁判绝对零静态引用,那么事情似乎工作正常。这基本上意味着我必须将程序重新设计到没有类直接相互交互的地方 - 它们触发工具栏订阅的事件,调用其他类中的方法。哎哟。

我应该选择那个模型(这可能是理想的,但我在这里很远)或者是否有一个我在这里缺少的简单修复?

其他说明:

  • 所有IE标签都在单独的进程中运行。
  • BHO /工具栏的运行方式与IE标签相同。
  • 我正在使用Add-In-Express for Internet Explorer来处理IE集成。
  • 该项目是为.NET 3.5编写的;加载程序使用.NET 2.0

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

问题解决但静态引用已经消失。我做了一些事情:

首先,我将目标.NET版本更改为4.0。显然,用4.0编写的BHO工作得更好 - 我找不到证实这种说法的链接,但我已经在某处读过了。

更重要的是,我完全取消了程序集中的静态引用。我摆脱了单身人士,而是在我的工具栏类中为每个前单身人士类创建了一个属性,它始终是唯一的。每当一个类需要引用前一个单例时,我就会传递对工具栏的引用。

所以......构造函数现在看起来像这样:

internal class RegistryData
{
     public RegistryData(Toolbar toolbar)
     {
          ToolbarRef = toolbar;
     }

     ...
}

让我们说RegistryData需要调用Messaging。

private void RegistryUpdated(int keyId)
{
    ToolbarRef.Messaging.SendMessage(keyId);
}

巨大的痛苦吧?几小时的工作。但问题解决了。如果这个问题只与Add-In-Express有关,我不会感到震惊。