2009-12-01 19 views
11

In base a this article se registro il mio oggetto COM con il modello di thread "Entrambi" o "Libero", tale oggetto deve essere completamente sicuro per i thread. In particolare, tutti gli accessi a variabili globali condivise devono essere sincronizzati e anche tutti gli accessi alle variabili membro devono essere sincronizzati. Questo è un grande sforzo.Perché dovrei utilizzare il modello di threading "Both" anziché "Free"?

Ora capisco che essere in grado di registrare il mio oggetto come utilizzando il modello di threading "gratuito" è vantaggioso e potrebbe valere la pena pagare il prezzo per renderlo completamente sicuro per i thread. Ma perché dovrei fare lo stesso e registrare il mio oggetto usando il modello di threading "Both"? Quale sarebbe il vantaggio? Come faccio a scegliere tra "Both" e "Free"?

risposta

20

Sia modello di threading

La ragione principale per la marcatura il componente a supportare il modello di threading "Entrambi" è per i miglioramenti delle prestazioni quando il componente viene chiamato da un Single Threaded Apartment (STA).

Se si contrassegna il componente come MTA e il componente viene creato da uno STA, il componente verrà creato in un appartamento MTA separato e lo "resultant inter-apartment marshaling might degrade performance enough to negate all the work put into making an efficient, free-threaded component". Tuttavia, se il modello di threading del componente è contrassegnato come "Entrambi", verrà creato all'interno dell'appartamento dell'oggetto STA e sarà possibile accedere direttamente.

Quindi, se si ritiene che il componente possa essere chiamato da uno STA (tutti gli oggetti COM VB6 sono STA) è possibile contrassegnare il modello di threading come "Entrambi".

Un buon articolo KB su OLE Threading Models.

libero modello di threading

Si potrebbe desiderare di utilizzare un modello di "Libero" filo Se il componente utilizza altri componenti che sono contrassegnati come "Free". Se il tuo componente è stato contrassegnato come "Entrambi", potrebbe verificarsi un eccessivo cambio di appartamento tra il componente "Entrambi" in esecuzione nello STA e nell'MTA. Come regola generale, provare a creare il componente il più vicino possibile al chiamante (ad esempio lo stesso appartamento) mentre funziona correttamente in tutti gli scenari.

Un'altra situazione che meriterebbe di contrassegnare il componente come "Libero" è se blocca in modo esplicito (ad esempio Thread.Sleep). Se il componente è contrassegnato come "Entrambi" e istanziato in uno STA, il componente bloccherebbe la pompa del messaggio STA.

Altre considerazioni e scenari

Se state pensando di usare il componente in IIS, poi ci sono altre cose da considerare. Per IIS, "Both" è l'impostazione consigliata. Principalmente per evitare problemi di blocco con i componenti threaded Apartment, l'accesso performante a COM + ObjectContext e il fatto che i componenti "gratuiti" utilizzano il contesto di sicurezza del sistema (se si richiede l'accesso al contesto di sicurezza dell'utente). Vedere Selecting a Threading Model for Components in IIS per ulteriori informazioni sulle considerazioni sul threading di IIS.

Altre cose da considerare sono il supporto COM + e il modo in cui i componenti si comportano se vengono eseguiti in COM + e se i puntatori all'interfaccia vengono passati e archiviati.

Un articolo eccellente è COM Threading and Application Architecture in COM+ Applications. Ha un focus su COM + ma parla anche di COM. Per la tua domanda, leggi la sezione intitolata "Threading Model Recommendations". Microsoft ha rimosso l'articolo originale, quindi collego a una copia.

+2

Questa è una grande spiegazione, tranne che ora non capisco perché contrassegnerei il mio oggetto come "Libero" e non "Entrambi" poiché sembra che "Entrambi" sia più vantaggioso. – sharptooth

+1

Perché potresti volerlo "forzare" nel MTA, ad es. Sarà accessibile da molti altri oggetti nel MTA e non vuoi che questi usino i proxy allo STA su cui il tuo oggetto è creato (da un utente VB6) – wqw

+0

Bene, se ci sono due thread: uno STA e un MTA e entrambi chiamano CoCreateInstance(), quindi ... Se un oggetto è contrassegnato come "Entrambi" viene creata una copia in STA e una in MTA. Le chiamate da Thread1 a STA e da Thread2 a MTA sono dirette, altre passano tramite proxy. Se l'oggetto è contrassegnato come "Libero", entrambe le copie si trovano in un MTA e solo le chiamate da Thread1 a MTA passano attraverso il proxy, altre chiamate sono dirette. È tutto molto bello, ma perché l'oggetto dovrebbe imporre il secondo e non lasciare che sia il problema dei clienti? – sharptooth

Problemi correlati