Pregunta

Estoy corriendo un servicio de Windows multiproceso que necesita llamar a una DLL de VB6. No hay documentación sobre este DLL VB6 y este sistema heredado es compatible con un proceso de negocio muy crítico.

A primera hora (primera rosca), esta DLL realiza bien. Como otros hilos necesitan tener acceso, se inicia proporcionar resultados erróneos.

leí uno chicos que dicen:

  

"Sólo tenga cuidado de una cosa si está utilizando Visual Basic 6. Su enhebrado   modelo se va a tener que cambiar a apartamentos de asistencia Si tiene   la ejecución de un servicio de multiproceso. VB sólo es compatible con múltiples   apartamentos de un único subproceso, pero .NET se ejecuta totalmente libre de roscado   normalmente. El subproceso que llama a la DLL de VB6 tiene que ser   compatible con la DLL ".

Otro tipo de equipo me dio la idea de poner este DDL en un dominio de aplicación separada. Pero no estoy seguro.

¿Cómo podemos trabajar con VB6 DLL llamada desde una aplicación de servicio de Windows en C # multiproceso?

¿Fue útil?

Solución

Cuando los hilos entran, está ahorrando objetos y reutilizarlos más adelante nuevos temas? Si es posible, crear los nuevos objetos para cada hilo. Tenemos una situación como esta con un DLL capa de datos que utilizamos. Si crea una conexión en un hilo, no puede ser utilizado de otra. Si crea una nueva conexión en cada hilo, que trabaja muy bien.

Si es lento para crear sus objetos, mirar a la clase ThreadPool y el atributo ThreadStatic. Threadpools reciclan el mismo conjunto de hilos y otra vez para hacer el trabajo, y ThreadStatic le permite crear un objeto que existe para un solo hilo. por ejemplo,

[ThreadStatic]
public static LegacyComObject myObject;

A medida que llega una petición, lo convierten en un trabajo y hacer cola en su grupo de subprocesos. Cuando se inicia el trabajo, comprobar si el objeto estático se inicializa;

void DoWork()
{ 
    if (myObject == null)
    { 
        // slow intialisation process
        myObject = New ...
    }

    // now do the work against myObject
    myObject.DoGreatStuff();
}

Otros consejos

Usted dice

  

Estoy corriendo una ventana multiproceso   servicio que necesita llamar a una DLL de VB6.   No hay documentación sobre este   DLL VB6 y este sistema heredado   soporta un negocio muy crítico   proceso.

y, al mismo tiempo que dice

  

A primera tiempo (1º hilo), esta DLL   funciona bien. Como otros hilos necesitan   acceso, se inicia proporcionar equivocada   resultados.

Me gustaría hacer muy seguro de que la administración es consciente de la falla que se está viendo ya que el código de apoyo al proceso de negocio crítico es viejo y no documentada, y está siendo utilizado de una manera que nunca fue pensado para ser utilizado, y estaba Nunca probado para ser utilizado. Apuesto a que nunca es también ha sido probado para ser utilizado desde .NET antes, ¿verdad?

Aquí está mi sugerencia, y esto es similar a algo que he implementado en realidad:

El VB6 DLL espera ser llamada en un solo hilo. No decepcionar a él! Cuando el servicio se inicia, hacer que se inicie un hilo del tipo apropiado (no puedo decir, ya que se me ha olvidado deliberadamente todo lo que STA / MTA cosas). Poner en cola las peticiones a ese hilo de acceso a la DLL de VB6. Todos han dicho acceso pasar por el solo hilo.

De este modo, en lo que se refiere a la DLL de VB6, que está funcionando exactamente como fue probado para funcionar.


Por cierto, esto es ligeramente diferente de lo que he implementado. Tenía un servicio web, no un servicio de Windows. Tenía una DLL de C, no VB6, y no era COM. Yo sólo refactorizado todos los accesos a la cosa en una sola clase, a continuación, poner las declaraciones de bloqueo alrededor de cada uno de los métodos públicos.

Este artículo sobre multithreading de Visual Basic 6 DLL proporciona una cierta penetración. Dice:

  

Para realizar un proyecto DLL ActiveX   multiproceso, seleccionar el deseado   enhebrar opciones en la ficha General   del cuadro de diálogo Propiedades del proyecto.

Este artículo dice que hay tres posibles modelos para elegir:

One thread of execution 
Thread pool with round-robin thread assignment 
Every externally created object is on its own thread 

Asumo que el valor predeterminado es one thread of execution, y que una de las otras dos opciones se debe seleccionar.

Es posible que desee echar un vistazo a esto: Linky

Y aquí es un fragmento que me llamó la atención:

  

Los objetos COM VB6 son objetos STA, que significa que deben ejecutarse en un subproceso STA.   ¿Te ha crear dos instancias del objeto a partir de dos subprocesos MTA, pero el propio objeto se ejecutará en un único (COM (OLE) creado) STA   hilo, y el acceso desde los dos hilos de MTA se calculan y sincronizados.   Así que lo que debe hacer es, inicializar los hilos como STA modo que cada objeto se ejecuta en su propio subproceso STA sin cálculo de referencias y   va a estar bien.

     

De todos modos, VB objetos COM estilo son siempre STA. Ahora con el fin de evitar que el cálculo de referencias de apartamentos y el hilo de conmutación es necesario crear   casos en STA inicializan apartamentos.   Tenga en cuenta también que cuando se establece el atributo [MTAThread] en Main, inicializar efectivamente el hilo principal como MTA, cuando se crea   casos de STA objetos de subprocesos MTA COM va a crear un hilo separado (no administrada) y inicializarlo como STA (esto se denomina la   predeterminado STA), se calculan todas las llamadas a objetos STA de subprocesos MTA (e incurrir en interruptores de rosca), en algunos casos IDispatch llamadas   fallará debido a fallas en el cálculo de referencias IP.   Así que el consejo es el uso STA (y por lo tanto, Visual Basic 6) objetos de apartamentos compatibles solamente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top