Delen via


Problemen met In-Process server-threading

Een in-process-server roept niet CoInitialize, CoInitializeExof OleInitialize aan om zijn threadingmodel te markeren. Voor threadbewuste DLL-objecten of in-process-objecten moet u het threadingmodel instellen in het register. Het standaardmodel wanneer u geen threadingmodel opgeeft, is één thread per proces. Als u een model wilt opgeven, voegt u de ThreadingModel--waarde toe aan de InprocServer32--sleutel in het register.

DLL's die ondersteuning bieden voor instantiëring van een klasseobject, moeten de functies implementeren en exporteren DllGetClassObject en DllCanUnloadNow. Wanneer een client een instantie van de klasse wil die door de DLL wordt ondersteund, zorgt een aanroep van CoGetClassObject (rechtstreeks of via CoCreateInstance) voor een aanroep van DllGetClassObject om een verwijzing naar zijn klasobject te verkrijgen wanneer het object in een DLL is geïmplementeerd. DllGetClassObject moet daarom meerdere klasseobjecten of één thread-veilig object kunnen weggeven (in feite alleen InterlockedIncrement/InterlockedDecrement op hun interne referentieaantallen).

Zoals de naam al aangeeft, wordt DllCanUnloadNow aangeroepen om te bepalen of het DLL-bestand dat wordt geïmplementeerd in gebruik is, zodat de aanroeper het veilig kan ontladen als dat niet het is. Oproepen naar CoFreeUnusedLibraries vanaf elke thread worden altijd via de hoofdthread van het appartement gerouteerd om DllCanUnloadNowaan te roepen.

Net als andere servers kunnen in-process-servers single-threaded, apartment-threaded of multithreaded zijn. Deze servers kunnen worden gebruikt door elke OLE-client, ongeacht het threadingmodel dat door die client wordt gebruikt.

Alle combinaties van interoperabiliteit van threading-modellen zijn toegestaan tussen clients en in-process-objecten. Interactie tussen een client en een in-process object dat verschillende threadingmodellen gebruikt, is precies zoals de interactie tussen clients en out-of-process servers. Wanneer voor een in-process server het threadingmodel van de client en de in-process server verschilt, moet COM zichzelf tussen de client en het object insluiten.

Wanneer een in-process object dat ondersteuning biedt voor het model met één thread tegelijk wordt aangeroepen door meerdere threads van een client, kan COM de clientthreads niet toestaan om rechtstreeks toegang te krijgen tot de interface van het object' is het object niet ontworpen voor dergelijke toegang. In plaats daarvan moet COM ervoor zorgen dat aanroepen worden gesynchroniseerd en alleen worden uitgevoerd door de clientthread die het object heeft gemaakt. Daarom maakt COM het object in het hoofdappartement van de klant en vereist dat alle andere clientappartementen toegang hebben tot het object met behulp van proxy's.

Wanneer een vrij gekoppeld appartement (multithreaded appartementmodel) in een client een in-process server met appartementthreads creëert, start COM een een-draads appartementmodel 'host'-thread in de client. Deze hostthread maakt het object aan, en de interfacepointer wordt teruggezonden naar de vrij-draads appartement van de client. Wanneer een enkelvoudig draadmodel in een client voor draadmodellen een vrij-dradige in-proces server creëert, start COM een vrij-dradige hostdraad (meerdraads appartement waarop het object zal worden gecreëerd en vervolgens terug wordt overgebracht naar het enkelvoudig draadzijdige client apartement).

Notitie

In het algemeen moet u, als u een aangepaste interface op een in-process server ontwerpt, ook de marshaling-code opgeven zodat COM de interface tussen clientappartementen kan marshalen.

 

COM helpt de toegang tot objecten die worden geleverd door een DLL met één thread te beveiligen door toegang te vereisen vanaf hetzelfde client appartement waarin ze zijn gemaakt. Bovendien moeten alle DLL-toegangspunten (zoals DllGetClassObject en DllCanUnloadNow) en globale gegevens altijd worden geopend door hetzelfde appartement. COM creëert dergelijke objecten in het hoofd appartement van de klant, waardoor het hoofd appartement directe toegang tot de aanwijzers van het object. Oproepen van de andere appartementen gebruiken interthread marshaling om van de proxy naar de stub in het hoofdappartement en vervolgens naar het object te gaan. Hierdoor kunnen COM-aanroepen naar het object synchroniseren. Interthread-oproepen zijn traag, dus het wordt aanbevolen dat deze servers worden herschreven om meerdere appartementen te ondersteunen.

Net als een server met één thread in proces, moet een object dat wordt geleverd door een dll van een appartementsmodel, worden geopend door hetzelfde client appartement waaruit het is gemaakt. Objecten die door deze server worden geleverd, kunnen echter worden gemaakt in meerdere appartementen van de client, zodat de server de toegangspunten moet implementeren (zoals DllGetClassObject en DllCanUnloadNow) voor multithreaded gebruik. Als bijvoorbeeld twee appartementen van een client tegelijkertijd twee exemplaren van het in-process object proberen te maken, kan DllGetClassObject gelijktijdig worden aangeroepen door beide appartementen. DllCanUnloadNow- moet worden geschreven, zodat het DLL-bestand niet wordt ontladen terwijl de code nog steeds wordt uitgevoerd in het DLL-bestand.

Als de DLL slechts één exemplaar van de klassefabriek biedt om alle objecten te maken, moet de klassefabriek-implementatie ook worden ontworpen voor multithreaded gebruik, omdat deze wordt benaderd door meerdere clients. Als de DLL steeds een nieuw exemplaar van de klassefactory maakt wanneer DllGetClassObject wordt aangeroepen, hoeft de klassefactory niet thread-safe te zijn.

Objecten die door de klassefactory zijn gemaakt, hoeven niet thread-safe te zijn. Zodra het is gemaakt door een thread, wordt het object altijd via die thread geopend en worden alle aanroepen naar het object gesynchroniseerd door COM. Het appartement model appartement van een klant die dit object maakt, krijgt een directe aanwijzer naar het object. Clientappartementen die van het appartement waarin het object is gecreëerd verschillen, moeten via proxy's toegang tot het object krijgen. Deze proxy's worden gemaakt wanneer de cliënt de interface tussen zijn appartementen verdraalt.

Wanneer een in-process DLL-ThreadingModel waarde is ingesteld op 'Both', kan een object dat door deze DLL wordt geleverd rechtstreeks (zonder proxy) worden gemaakt en gebruikt in enkelvoudige of multithreaded client-omgevingen. Het kan echter rechtstreeks worden gebruikt binnen het appartement waarin het werd gemaakt. Om het object aan een ander appartement te geven, moet het object worden voorbereid voor overdracht. Het DLL-object moet een eigen synchronisatie implementeren en kan tegelijkertijd worden geopend door meerdere clientappartementen.

Com biedt de CoCreateFreeThreadedMarshaler functie om de prestaties te versnellen voor gratis thread-toegang tot DLL-objecten in het proces. Met deze functie maakt u een draadvrij marshaling-object dat kan worden samengevoegd met een in-process-serverobject. Wanneer een clientappartement binnen hetzelfde proces toegang nodig heeft tot een object in een ander appartement, biedt het samenvoegen van de free-threaded marshaler de client een directe pointer naar het serverobject, in plaats van naar een proxy, wanneer de client de interface van het object naar een ander appartement transformeert. De client hoeft geen synchronisatie uit te voeren. Dit werkt alleen binnen hetzelfde proces; standaard marshaling wordt gebruikt voor een verwijzing naar het object dat naar een ander proces wordt verzonden.

Een object dat wordt geleverd door een in-process DLL die alleen free threading ondersteunt, is een free-threaded object. Het implementeert een eigen synchronisatie en kan tegelijkertijd worden geopend door meerdere clientthreads. Deze server marsalleert geen interfaces tussen threads, dus deze server kan rechtstreeks worden gemaakt en gebruikt (zonder proxy) alleen door multithreaded apartments in een client. Appartementen met één thread die het maken, krijgen er toegang toe via een proxy.

toegang tot interfaces in verschillende appartementen

Het Threadingmodel Kiezen

Meerdraadse Appartementen

processen, threads en appartementen

Single-Threaded en multithreaded communicatie

Single-Threaded Appartementen