2010-09-03 19 views
13

He escrito una API que se utilizará en el mismo cuadro en (1) un servicio de Windows, (2) una aplicación web y (3) una aplicación de formularios de Windows. Todos necesitan compartir un conjunto muy pequeño de datos comunes (unos pocos enteros, una fecha y una cadena que podría poner como propiedades de una sola clase).Bloqueo de proceso cruzado en C#

¿Qué tipo de mecanismo de bloqueo puedo usar en el proceso cruzado para que los tres procesos puedan compartir los recursos de manera segura y no tener conflictos?

Sin bases de datos, busque una solución que no requiera dependencias adicionales. Preferiblemente, la solución usaría la memoria compartida, o el sistema de archivos de alguna manera.

+0

El título de su pregunta sugiere que se trata de "bloqueo", pero la pregunta real parece ser solo acerca de los datos. Por favor aclara –

+1

¡Has terminado de contar! – Wells

Respuesta

17

Para el bloqueo de procesos cruzados en C#/.Net, puede usar un named system Mutex.

+0

Utilicé Mutex para esto. Pero solo un proceso es obtener el bloqueo. Otros no pueden lograr este bloqueo. He publicado una pregunta http://stackoverflow.com/questions/41359056/how-can-i-distribute-the-mutex-lock-between-processes/41359378#41359378 – TBAG

+1

@TBAG Veo que estás enviando spam con Stackoverflow con muchos preguntas (y comentarios sobre preguntas no relacionadas) sobre este "problema" que está experimentando. Se utiliza un mutex para garantizar el acceso exclusivo a un recurso compartido en todos los procesos. No es para programar el trabajo o el acceso a través de múltiples subprocesos. Su comprensión de cómo funciona el mutex: "Si tres métodos llaman a este constructor, todos deberían llamar de forma secuencial o de forma rutinaria". - no es correcto y es por eso que no obtienes el comportamiento que esperas. –

2

Utilice un objeto EventWaitHandle para construir un evento nombrado que cada proceso puede bloquear o bloquear. Funciona en .NET 2.0 y posterior.

1

Según su pregunta, parece que lo que necesita es la comunicación de proceso cruzado. Entonces, uno de los procesos aloja los datos compartidos y los otros procesos necesitan acceder a esos datos.

Si lo anterior es correcto, puede usar el bloqueo simple en proceso como un Monitor para proteger los datos compartidos y exponer un punto final WCF para proporcionar acceso a los datos de otro proceso. El uso de un transporte de Canalización nominal para la comunicación WCf será muy eficiente para la comunicación entre procesos en el mismo cuadro.

No habría necesidad de bloqueo de proceso cruzado, a menos que utilice un recurso compartido como un archivo mapeado de memoria para compartir los datos, pero para ser honesto esto sería engorroso y requiere que maneje muchas cosas manualmente que WCF tomaría cuidado con el beneficio de poder escalar el cuadro individual a múltiples cajas si alguna vez lo necesita.

1

Si toda su aplicación residiría en una máquina, entonces podría usar primitivas de sincronización entre procesos como mutexes con nombre y memoria compartida.

Pero creo que un enfoque mucho mejor sería usar algo así como los servicios de WCF (que podrían residir en el servicio de Windows) y exponer toda la información necesaria a través de un contrato específico. En este caso, toda esta aplicación podría residir en diferentes máquinas, pero de todos modos esta solución es más limpia y robusta.

+0

más uno para la visión lejana. Los mutexes pueden ser una solución de "solución rápida" pero nunca infalibles. :) –

1

Puede usar MSMQ para proporcionar colas compartidas entre sus aplicaciones, con una de las aplicaciones actuando como maestra; el servicio de Windows sería la mejor opción si siempre se está ejecutando.

Uso System.Data.Sqlite para comunicarme entre servicios y aplicaciones de Windows. A pesar de que dijo que no hay bases de datos, puede encontrar esto como un compromiso digno. Es una base de datos incrustada sin carga administrativa. Lo "envía" al incluir una sola DLL en sus aplicaciones, y guarda sus datos en un solo archivo.

Piense en ello como un archivo persistente al que accede utilizando instrucciones SQL a través de ADO.Net; incluso tiene una interfaz LINQ. Se bloquea a través de transacciones estándar (con reversión) y también ofrece encriptación. Puede modificar y ver su contenido utilizando Visual Studio Service Explorer. Funciona en .Net 3.5 y .Net 4. Y es de código abierto sin restricciones. Puede agregar columnas y tablas sin romper la funcionalidad existente. Dado que la implementación es tan simple como agregar una DLL a su solución, es mucho más fácil de implementar y de brindar soporte. Y dado que la cadena de conexión apunta a un archivo, facilita el acceso desde máquinas remotas. Quizás no sea tan elegante como colas compartidas o mutexes, pero es algo muy simplificado para mí.

+0

"A pesar de que dijo que no hay bases de datos, puede encontrar esto como un compromiso digno". Dudoso, considerando que es a la vez una base de datos y una dependencia adicional; ambos los descartó explícitamente como soluciones. – Dan

Cuestiones relacionadas