C#Marshalling objetos COM entre hilos
multithreading apartments (1)
Parece que está utilizando StaTaskScheduler
Stephen Toub como parte de una lógica "con estado", donde sus objetos COM residen en los límites de StartNew
. Si ese es el caso, asegúrese de crear y utilizar estos objetos en el mismo hilo StaTaskScheduler
STA y en ningún lugar fuera de él. Entonces no tendrías que preocuparte por la clasificación de COM en absoluto. No hace falta decir que debe crear StaTaskScheduler
con solo un hilo, es decir, numberOfThreads:1
.
Esto es lo que quiero decir:
var sta = new StaTaskScheduler(numberOfThreads:1);
var comObjects = new { Obj = (ComObject)null };
Task.Factory.StartNew(() =>
{
// create COM object
comObjects.Obj = (ComObject)Activator.CreateInstance(
Type.GetTypeFromProgID("Client.ProgID"));
}, CancellationToken.None, TaskCreationOptions.None, sta);
//...
for(int i=0; i<10; i++)
{
var result = await Task.Factory.StartNew(() =>
{
// use COM object
return comObjects.Obj.Method();
}, CancellationToken.None, TaskCreationOptions.None, sta);
}
Si Obj.Method()
devuelve otros objetos COM, debe mantener el resultado en el mismo "apartamento" de StaTaskScheduler y acceder desde allí también:
var comObjects = new { Obj = (ComObject)null, Obj2 = (AnotherComObject)null };
//...
await Task.Factory.StartNew(() =>
{
// use COM object
comObjects.Obj2 = comObjects.Obj.Method();
}, CancellationToken.None, TaskCreationOptions.None, sta);
Si también necesita manejar eventos originados por Obj
, verifique esto:
Me confundo mucho sobre si los objetos COM del C # Marshal están entre los hilos. Para este fin, tengo una aplicación que está cargando un conjunto de archivos en una tarea paralela. Estoy usando StaTaskScehduler para cargar los archivos usando el objeto COM. Una vez que el objeto COM está cargado, estoy almacenando el objeto en una lista central.
Luego trato de realizar algún procesamiento con estos datos, nuevamente usando STATaskScheduler. Sin embargo, en este punto, me encontré con un problema. Recibo una excepción de la siguiente manera:
An unhandled exception of type ''System.Runtime.InteropServices.InvalidComObjectException'' occurred in MadCat.exe
Additional information: COM object that has been separated from its underlying RCW cannot be used
Ahora entiendo que recibo este error porque el objeto no se ha agrupado en el nuevo hilo. Pensé que esto era algo que C # hace por ti?
¿Cómo puedo crear un objeto COM con rosca de apartamento en un hilo y luego usarlo desde otro hilo?
¿Estoy ladrando el árbol equivocado aquí? ¿No debería usar el apartamento Sta para mis hilos? Puedo garantizar que el objeto nunca tenga acceso desde múltiples hilos simultáneamente. Cualquier pensamiento muy apreciado.
Editar : El objeto COM se define de la siguiente manera:
[
coclass,
threading( apartment ),
vi_progid( [Namespace.Class] ),
progid( [Namespace.Class].6 ),
version( 6.0 ),
uuid( GUID_C[Class] ),
helpstring( [Class]" Class" )
]
Entonces, según tengo entendido, este es un objeto de apartamento roscado, ¿verdad? Acabo de intentar usar un programador de tareas modificado que no establece el estado del departamento (¿MTA por defecto?). Este objeto parece funcionar cuando lo creo en un hilo y lo uso desde otro. ¿Esto es seguro o volverá para morderme de otra manera?
El modelo de enhebrado de COM siempre me ha confundido: /