412 Stimmen

Können Sie STA und MTA erklären?

Können Sie STA und MTA mit Ihren eigenen Worten erklären?

Was sind Apartment-Threads und beziehen sie sich nur auf COM? Wenn ja, warum?

13voto

Kevin C. Punkte 261

Nach meinem Verständnis wird das "Apartment" verwendet, um die COM-Objekte vor Multithreading-Problemen zu schützen.

Wenn ein COM-Objekt nicht thread-sicher ist, sollte es als STA-Objekt deklariert werden. Dann kann nur der Thread, der es erstellt, darauf zugreifen. Der Erstellungs-Thread sollte sich selbst als STA-Thread deklarieren. Unter der Haube speichert der Thread die STA-Informationen in seinem TLS (Thread Local Storage). Wir nennen dieses Verhalten, dass der Thread eine STA-Wohnung betritt. Wenn andere Threads auf dieses COM-Objekt zugreifen wollen, sollten sie den Zugriff an den Erstellungs-Thread weiterleiten. Im Grunde verwendet der Erstellungs-Thread den Nachrichtenmechanismus, um die gebundenen Aufrufe zu verarbeiten.

Wenn ein COM-Objekt thread-sicher ist, sollte es als MTA-Objekt deklariert werden. Auf das MTA-Objekt kann von mehreren Threads aus zugegriffen werden.

5voto

beanmf Punkte 443

Code, der COM-Objekt-DLLs aufruft (z. B. zum Lesen proprietärer Datendateien), kann in einer Benutzeroberfläche problemlos funktionieren, aber in einem Dienst auf mysteriöse Weise hängen bleiben. Der Grund dafür ist, dass seit .Net 2.0 Benutzeroberflächen STA (thread-safe) voraussetzen, während Dienste MTA voraussetzen (davor setzten Dienste STA voraus). Einen STA-Thread für jeden COM-Aufruf in einem Dienst zu erstellen, kann einen erheblichen Overhead verursachen.

2voto

lfree Punkte 1659

Dieser Artikel erklärt STA und MTA sehr deutlich.

COM Apartments verstehen, Teil I
COM-Wohnungen verstehen, Teil II

Hinweise darauf, was ein Apartment ist:

  • Ein Apartment ist eine Gleichzeitigkeitsgrenze; es ist ein imaginärer Rahmen, der um Objekte und Client-Threads gezogen wird und COM-Clients und COM-Objekte mit inkompatiblen Threading-Eigenschaften voneinander trennt.
  • Jeder Thread, der COM verwendet, und jedes Objekt, das diese Threads erstellen, wird einem Apartment zugewiesen.
  • Wenn ein Thread die COM-Funktion CoInitialize o CoInitializeEx Funktion wird dieser Faden in einer Wohnung platziert. Und wenn ein Objekt erstellt wird, wird es ebenfalls in einem Apartment platziert.
  • Immer wenn eine neue Wohnung angelegt wird, weist COM ein Wohnungsobjekt auf dem Heap zu und initialisiert es mit wichtigen Informationen wie der Wohnungskennung und dem Wohnungstyp. Wenn COM einem Apartment einen Thread zuweist, speichert es die Adresse des entsprechenden Apartmentobjekts im thread-lokalen Speicher (TLS).

0voto

Pekka Ylönen Punkte 1

Nebenbemerkung: Wenn Sie einige PowerShell 2.0-Snap-Ins verwenden, müssen Sie PowerShell Version 3 oder höher mit der Option -MTA starten, um sie zu verwenden. Das Wohnungsmodell von PowerShell 2 ist MTA, während spätere Versionen standardmäßig STA verwenden. Ein weiterer Punkt ist die Bitdichte. Normale Aufrufe in Apartment werden nicht marshalled (direkte Aufrufe), wenn also Ihr Aufrufer x64 ist, muss der Empfänger auch x64 sein. Der einzige Weg, dies zu umgehen, ist die Verwendung von Remote Procedure Call (RPC), die eine riesige Menge an Overhead hinzufügt (ein neuer 32-Bit-Prozess wird gestartet, um die Snap-In-DLL zu laden und das Ergebnis auf irgendeine Weise abzufragen).Für Entwickler: Veröffentlichen Sie immer die Typbibliothek - das macht die Entdeckung und Verwendung von COM-Objekten viel einfacher! Jede Schnittstelle sollte öffentlich und eindeutig sein - die Implementierung kann proprietär oder Open Source sein.

Eine andere Situation

Exemple :

 IStorage_vtbl** reference; // you got it by some means of factory

 public unsafe int OpenStorage(char* pwcsName, IStorage pstgPriority, uint grfMode, char** snbExclude, uint reserved, IStorage* ppstg)
 {
     IStorage_vtbl** @this = (IStorage_vtbl**)reference;
     IStorage_vtbl* vtbl = *@this;
     if (vtbl == null)
         throw new InvalidComObjectException();
     Delegate genericDelegate = Marshal.GetDelegateForFunctionPointer(vtbl->method_6, typeof(delegate_6));
     delegate_6 method = (delegate_6)genericDelegate;
     return method(@this, pwcsName, pstgPriority, grfMode, snbExclude, reserved, ppstg);
 }

Dieses Codefragment fügt einfach den "this"-Zeiger der Instanz für den tatsächlichen Aufruf des COM-Subsystems hinzu Ist dieser Aufruf also zum Öffnen einer Instanz von IStorage STA oder MTA?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X