2016-05-02 17 views
0

Ich habe ein IE-Browser-Helper-Objekt. Das BHO ist als ein COM-Objekt implementiert. Zuerst dachte ich, dass der Lebenszyklus des BHO auf einem pro-Seite Navigationszyklus war, aber es scheint tatsächlich auf einem Ereignis-Lebenszyklus zu sein. Dies bedeutet, dass das BHO für jedes Ereignis instanziiert und ausgeführt wird und es viele Ereignisse pro Navigation gibt. Ich brauche einen kritischen Abschnitt, der vom BHO aufgerufen wird, der vom Lebenszyklus des BHO getrennt ist. Leider scheint es, dass statische Variablen nicht beibehalten werden, da jedes Ereignis seinen eigenen COM-Server erhält. Ich denke, dass die Lösung darin besteht, einen separaten Prozess zu starten, der mit dem IE startet (das BHO wird nach einer laufenden Instanz suchen und, falls es gefunden wird, es verwenden, andernfalls wird es den Prozess erzeugen). Dann wäre der kritische Abschnitt innerhalb des Sekundärprozesses. Wäre dies der beste Weg, um dieses Szenario zu bewältigen?Wie Sie einen kritischen Abschnitt in einer Windows COM-Komponente einrichten und verwalten

+0

COM-Objekte werden als Referenz gezählt. Wenn Sie Ihr COM-Objekt überleben müssen, erhöhen Sie die Anzahl der Referenzen um eins. – IInspectable

+0

Also, wenn IE es dereferenziert, dann hat es immer noch eine Referenz, so dass es überlebt. Bedeutet das, dass, wenn IE eine andere Referenz benötigt, die letzte noch vorhanden ist und wiederverwendet wird? –

+0

Wenn ich in der AddRef-Methode 2 anstelle von 1 zurückgebe, passiert der Versand an den Event-Handler nie, da ich spekuliere, dass der IE einen Wert von 1 für den AddRef erwartet und jeder andere Wert als Fehler angesehen wird. Natürlich habe ich keine Möglichkeit, dies empirisch zu beweisen, aber anekdotisch scheint dies zu sein, was passiert. –

Antwort

0

Ich bin nicht so vertraut mit BHO, aber ich kann Ihnen sagen, was aus der Sicht der COM geht.

Internet Explorer (der COM-Client) entscheidet, wann er ein neues COM-Objekt erstellen möchte; Sie haben keine Kontrolle darüber. Sie sagen, IE erstellt ein Objekt pro Ereignis; Ich weiß es nicht, aber ich glaube dir.

Das Problem besteht darin, dass Sie freigegebene Daten (es ist statisch, so dass es freigegeben ist) aus dem Konstruktor des Objekts initialisieren. Das kannst du nicht tun. Das kann nur funktionieren, wenn es nur eine Instanz Ihres Objekts pro Prozess zu einem bestimmten Zeitpunkt geben kann und die Regeln von COM dies nicht zulassen. Selbst wenn IE das gleiche Objekt pro Seitennavigationszyklus verwenden würde, was würde passieren, wenn Ihr IE-Prozess mehrere Seiten geöffnet hätte? Die freigegebenen Daten müssen außerhalb der Objekte initialisiert werden.

Haben Sie eine statische Variable in Betracht gezogen, die von einer statischen Methode initialisiert wurde, die die Tat ausführt?

Es gibt auch das Singleton-Muster, das ATL unterstützt, aber ich empfehle es nicht. IE nimmt wahrscheinlich an, dass, wenn es nach einem neuen Objekt fragt, es ein neues Objekt erhält, nicht eine Kopie des vorhandenen Objekts. Spiele keine Tricks hinter dem Rücken von IE.

Der genaue Mechanismus, den Sie verwenden sollten, hängt von den Details ab, was Sie zu tun versuchen. Was ist der genaue Umfang der gemeinsamen Daten? Sie geben nicht viele Details an, aber Sie haben "Critical Section" gesagt, so dass Multithreading involviert ist und das in einer DLL wirklich knifflig sein kann.

Ich frage mich: Sind Sie sicher, dass Sie wirklich kritische Abschnitte benötigen? Das IE-Objektmodell ist Single-Apartment-threaded (STA) und ich stelle mir vor, dass das BHO-Protokoll auch STA ist. In diesem Fall müssen Sie sich keine Gedanken über Threads oder kritische Abschnitte machen, es sei denn, Sie erstellen selbst Threads.

Einige Erläuterungen über die Kette von Kommentaren unter der Frage:

Künstlich den Rückgabewert Release zu erhöhen() oder AddRef() ist legal, aber ändert nichts. Es ist üblich, dass beide Methoden eine echte Referenzzahl zurückgeben, aber das ist nur ein Vorteil für Debugging-Zwecke und Sie können sich nicht darauf verlassen. Das Objekt muss nur einen Wert ungleich Null zurückgeben - einen Wert ungleich null -, wenn mindestens eine ausstehende Referenz vorhanden ist.

Wenn Sie AddRef() auf sich selbst anwenden, wird Ihre Codierungslast nur noch (erheblich) erhöht, weil Sie diese zusätzliche Referenz verfolgen müssen und sie irgendwann irgendwie loswerden müssen. Und es hat keinerlei Auswirkungen darauf, wie oder wann der Internet Explorer ein neues Objekt anfordert. Es kann keine Auswirkungen haben, wie Sie aus meinem vorherigen Punkt ableiten können, da Internet Explorer nicht weiß, wie viele ausstehende Referenzen das Objekt hat. Es interessiert nur, wie viele Referenzen IE selbst besitzt. Ich denke, du hast das schon selbst entdeckt.IE erwartet nicht 1 oder 2 von AddRef(); es erwartet nicht Null.