2010-11-08 7 views
10

Considere el siguiente escenario: estoy ejecutando mi aplicación que, durante su ejecución, tiene que ejecutar otro proceso y solo después de que el segundo proceso finalice la inicialización específica interna, ¿puede mi primer proceso continuar Por ejemplo:Sincronización de 2 procesos usando objetos de sincronizaciones entre procesos - Mutex o AutoResetEvent

... 
// Process1 code does various initializations here 
Process.Start("Process2.exe"); 
// Wait until Process2 finishes its initialization and only then continue (Process2 doesn't exit) 
... 

Veo varias opciones:

  1. objeto mutex - mutex viene a la mente cuando se considera la comunicación entre procesos, sin embargo, no puedo ver una manera de causar Process1 que esperar para una automática mutex que él mismo generó Puedo hacer que Process2 cree un mutex y esperar en Process1 hasta que se cree el Mutex (usando polling y la función Mutex.OpenExisting)
  2. AutoResetEvent - Esos serían perfectos para la tarea, sin embargo, parece que en .NET estos no se puede usar para la comunicación entre procesos.
  3. CreateEvent - Puedo usar P/Invoke y usar la función CreateEvent de Win32. En teoría, podría proporcionarme todo lo que necesito. Preferiría no usar funciones nativas, sin embargo, si es posible.
  4. Utilice el archivo externo - La manera más fácil sería simplemente usar algún objeto externo del sistema operativo (archivo, registro, etc.). Sin embargo, esto parece bastante hacky, sin embargo.

Estaría encantado de escuchar su opinión sobre este caso.

Gracias!

Respuesta

10

sólo iba a editar this answer, pero no parece correcto. Así que publicaré mi propio ...

De acuerdo con la página Threads for C#, que tiene muchos tutoriales de sincronización, AutoResetEvent no se puede utilizar para la sincronización entre procesos.


Sin embargo, se puede usar un nombre EventWaitHandle para la sincronización entre procesos. En la página anterior, visite la sección Creating a Cross-Process EventWaitHandle.

La forma en que este trámite es directa:

Proceso 1

EventWaitHandle handle = new EventWaitHandle(
    false,        /* Create handle in unsignaled state */ 
    EventResetMode.ManualReset,   /* Ignored. This instance doesn't reset. */ 
    InterprocessProtocol.EventHandleName /* String defined in a shared assembly. */ 
); 

ProcessStartInfo startInfo = new ProcessStartInfo("Process2.exe"); 
using (Process proc = Process.Start(startInfo)) 
{ 
    //Wait for process 2 to initialize. 
    handle.WaitOne(); 

    //TODO 
} 

Proceso 2

//Do some lengthy initialization work... 

EventWaitHandle handle = new EventWaitHandle(
    false,       /* Parameter ignored since handle already exists.*/ 
    EventResetMode.ManualReset,   /* Explained below. */ 
    InterprocessProtocol.EventHandleName /* String defined in a shared assembly. */ 
); 
handle.Set(); //Release the thread waiting on the handle. 

Ahora, con respecto a la EventResetMode. Si elige EventResetMode.AutoReset o EventResetMode.ManualReset depende de su aplicación.

En mi caso, necesitaba un reinicio manual porque tengo muchos procesos conectados al mismo proceso. Por lo tanto, una vez que este mismo proceso se haya inicializado, todos los demás procesos deberían poder funcionar. Por lo tanto, el mango debe dejarse en un estado señalado (sin reinicio).

Para que un retorno automático podría ser útil si tiene que realizar la inicialización para cada vez Proceso 1 inicia proceso .


Nota al pie: El InterprocessProtocol.EventHandleName es sólo una constante envuelto dentro de una DLL que tanto proceso 1 y proceso 2 referencia. No es necesario que haga esto, pero lo protege de escribir erróneamente el nombre y causar un punto muerto.

10

consideraría ** AutoResetEvent **. se pueden usar para la comunicación entre procesos y son relativley rápidos. ver el siguiente enlace: Threads for c#

leen la creación de una sección EventWaitHandle Cruzado ...

+3

AutoResetEvent puede ser solo local. Pero tienes razón: EventWaitHandle es exactamente lo que estaba buscando. ¡Gracias! – VitalyB

+0

¿Por qué no se pueden utilizar AutoResetEvent y ManualResetEvent para la comunicación entre procesos? Ambos derivan de EventWaitHandle – caa

Cuestiones relacionadas