c# - train - paradas del tren c
Peligros de C#MTA thread creando el objeto STA COM (1)
Actualmente estoy viendo un problema que tenemos en un servicio de Windows de .Net Framework 2.0 (C #) que tiene un número X de subprocesos MTA que ejecutan acceso a los componentes COM. Cada subproceso inicializa su propia instancia del objeto componente com. El objeto componente com no tiene ningún elemento UI. Es simplemente lógica de negocios que se comunica con una base de datos de servidor sql y un dll C # con una interfaz com que a su vez hace comunicación de socket y acceso a la misma base de datos del servidor sql.
A través de mi investigación, descubrí que no debería crear instancias de componentes STA COM en un hilo MTA, pero no puedo encontrar ningún texto específico para decir cuáles son los peligros de esto o tal vez es el hecho de que no entiendo los apartamentos COM threading. está bien.
¿Habría problemas de concurrencia con el modelo descrito anteriormente? Incluso si cada subproceso MTA está creando su propio objeto STA COM?
Editar
El problema con el que nos estamos encontrando es una referencia de objeto no configurada como instancia de un error de objeto en el setter de la cadena de conexión en el siguiente bloque de código. Esto ocurre dentro del objeto COM de C # que llama el objeto COM de C ++:
IDbConnection connection;
//Code omitted for brevity where connection is initialized
connection.ConnectionString = myConnectionString;
Tipo de excepción: System.NullReferenceException Mensaje: Referencia de objeto no establecida en una instancia de un objeto. Datos: System.Collections.ListDictionaryInternal TargetSite: Void ConnectionString_Set (System.String) en System.Data.OracleClient.OracleConnection.ConnectionString_Set (String value) en System.Data.OracleClient.OracleConnection.set_ConnectionString (valor de cadena)
Hay cuatro "peligros" básicos al realizar llamadas desde el MTA:
el objeto COM es apartamento enhebrado, muy común, y la llamada debe ser ordenada al apartamento que posee el objeto. La redacción técnicamente correcta para "STA COM". Eso es costoso , las llamadas calculadas a métodos pequeños suelen ser 10.000 veces más lentas.
el objeto COM no admite un proxy para ordenar la llamada. Eso es muy fácil de descubrir, la llamada fallará con E_NOINTERFACE.
el programador cliente no se da cuenta de que está realizando una llamada desde el MTA y olvida ordenar el puntero de la interfaz. COM no puede evitar esto en llamadas realizadas a un servidor COM en proceso. No puede cometer este error en un programa .NET, el CLR siempre se generará, pero es fácil de hacer en otros entornos de tiempo de ejecución. Esto de lo contrario invoca la ira común de realizar llamadas inseguras con subprocesos, funciona cuando depura el código, falla al azar en producción y es imposible depurar.
el autor COM ha publicado su componente para ser compatible con MTA al declarar ThreadingModel como Both o Free. Pero en realidad no puso a prueba su código lo suficiente, escribir un código seguro es extremadamente difícil. Especialmente peligroso en las clases .NET de [ComVisible] porque se registran automáticamente como Ambos y es muy fácil olvidarse completamente de probar el código contra esa promesa.
Su fragmento es demasiado inescrutable para hacer la llamada, pero es un posible candidato para la cuarta viñeta. De lo contrario, no parece que COM esté involucrado en absoluto. Los proveedores de datos como Oracle son normalmente libres y probados exhaustivamente por cientos de miles de programadores.