2009-12-01 3 views
11

Nach this article wenn ich mein COM-Objekt entweder mit "Both" oder "Free" Threading-Modell registriert, muss dieses Objekt vollständig Thread-sicher sein. Insbesondere müssen alle Zugriffe auf globale gemeinsame Variablen synchronisiert sein und alle Zugriffe auf Mitgliedsvariablen müssen ebenfalls synchronisiert sein. Das ist eine Menge Mühe.Warum würde ich "Both" COM-Threading-Modell anstelle von "Free" verwenden?

Jetzt verstehe ich, dass in der Lage, mein Objekt als "Free" -Threading-Modell registrieren ist vorteilhaft und könnte es sich lohnen, den Preis für die Herstellung völlig Thread-Safe. Aber warum sollte ich das gleiche tun und mein Objekt stattdessen mit dem "Both" -Threading-Modell registrieren? Was wäre der Vorteil? Wie wähle ich zwischen "Both" und "Free"?

Antwort

20

Beide Threadingmodell

Der Hauptgrund für die Komponente als unterstützende Threading-Modell Kennzeichnung „Both“ für Leistungsverbesserungen ist, wenn die Komponente aus einem Single Threaded Apartment (STA) aufgerufen wird. Wenn Sie Ihre Komponente als MTA markieren und Ihre Komponente in einer STA erstellt wird, wird Ihre Komponente in einer separaten MTA-Wohnung und der "resultant inter-apartment marshaling might degrade performance enough to negate all the work put into making an efficient, free-threaded component" erstellt. Wenn das Threadingmodell Ihrer Komponente jedoch als "Beide" markiert ist, wird es in der Wohnung des STA-Objekts erstellt und direkt darauf zugegriffen.

Wenn Sie also glauben, dass Ihre Komponente aus einer STA heraus aufgerufen werden kann (alle VB6-COM-Objekte sind STA), können Sie das Threading-Modell als "Both" markieren.

Ein guter KB-Artikel auf .

Freies Threadingmodell

Sie können ein „Free“ Thread-Modell verwenden möchten, wenn Ihre Komponente andere Komponenten verwendet, die als „Free“ gekennzeichnet sind. Wenn Ihre Komponente als "Beide" markiert wurde, kann es zu einem übermäßigen Wechsel der Wohnung zwischen der Komponente "Beide" in der STA und dem MTA kommen. Versuchen Sie in der Regel, die Komponente so nah wie möglich am Anrufer zu erstellen (d. H. Dieselbe Wohnung), während sie in allen Szenarien ordnungsgemäß funktioniert.

Eine andere Situation, die Ihre Komponente als "Frei" markieren würde, ist, wenn es explizit blockiert (z. B. Thread.Sleep). Wenn die Komponente in einer STA als "Both" markiert und instanziiert wird, würde die Komponente die STA-Nachrichtenpumpe blockieren.

Weitere Überlegungen und Szenarien

Wenn Sie über die Verwendung der Komponente in IIS planen, dann gibt es andere Dinge zu beachten. Für IIS ist "Beide" die empfohlene Einstellung. Vor allem, um Locking-Probleme mit Apartment-Thread-Komponenten zu vermeiden, performanter Zugriff auf COM + ObjectContext und die Tatsache, dass "Free" Threaded-Komponenten den System-Sicherheitskontext verwenden (wenn Sie Zugriff auf den Sicherheitskontext des Benutzers benötigen). Weitere Informationen zu Überlegungen zum IIS-Threading finden Sie unter Selecting a Threading Model for Components in IIS.

Andere Dinge zu berücksichtigen sind COM + Unterstützung und wie sich Ihre Komponenten verhalten, wenn sie in COM + ausgeführt werden und ob Schnittstellenzeiger übergeben und gespeichert werden. Ein ausgezeichneter Artikel ist COM Threading and Application Architecture in COM+ Applications. Es hat einen COM + -Fokus, behandelt aber auch COM. Für Ihre Frage lesen Sie den Abschnitt "Threading Model Recommendations". Microsoft hat den Originalartikel entfernt, also verlinke ich auf eine Kopie.

+2

Das ist eine großartige Erklärung, außer dass ich jetzt nicht verstehe, warum ich mein Objekt als "frei" und nicht als "beide" markieren würde, da "Both" besser aussieht. – sharptooth

+1

Weil Sie es möglicherweise im MTA "erzwingen" möchten, dh es wird von vielen anderen Objekten im MTA zugegriffen und Sie möchten nicht, dass diese Proxies für die STA verwenden, auf der Ihr Objekt erstellt wird (von einem VB6-Consumer) – wqw

+0

Nun, wenn es zwei Threads gibt - eine STA und ein MTA und beide CoCreateInstance() aufrufen, dann ... Wenn ein Objekt als "Both" markiert ist, wird eine Kopie in STA und eine in MTA erstellt. Die Aufrufe von Thread1 an STA und von Thread2 an MTA sind direkt, andere gehen durch Proxies. Wenn das Objekt als "Frei" markiert ist, befinden sich beide Kopien in einem MTA, und nur die Anrufe von Thread1 zu MTA werden über Proxy weitergeleitet, andere Aufrufe sind direkt. Das ist alles cool, aber warum sollte das Objekt letzteres durchsetzen und es nicht das Problem der Clients sein lassen? – sharptooth

Verwandte Themen