13

Estoy tratando de utilizar un mutex por primera vez y tienen el siguiente código que se ejecuta en dos casos separados del programaabandonado mutex excepción

public void asynchronousCode() 
    { 
     using (var mutex = new Mutex(false, "mySpecialMutex")) 
     { 
      if (!mutex.WaitOne(1000, false)) 
      { 
       Console.WriteLine("First check - some one locked the mutex"); 
      } 

      if (!mutex.WaitOne(3000, false)) 
      { 
       Console.WriteLine("Second check- some one locked the mutex"); 
      } 
      else 
      { 
       Console.WriteLine("I got the mutex"); 
       Console.WriteLine("sleeping"); 
       Thread.Sleep(3000); 
       Console.WriteLine("Awaking and Releasing mutex"); 
       mutex.ReleaseMutex(); 
      } 
     } 
    } 

Cuando ejecuto esto, uno de los casos (el que yo ejecutar primero) imprime

I got the mutex 
sleeping 
awaking and releasing mutex 

las otras impresiones ejemplo

First check - some one locked the mutex 

y tan pronto como la primera inst Ance arrienda el mutex, se estrella en el segundo estado de espera con la excepción

The wait completed due to an abandoned mutex. 

¿Alguna idea de por qué estoy recibiendo esta excepción y cómo puedo evitarlo?

Solución: Probablemente debería haber leído la documentación del mdsn con mayor claridad. Gracias Andrew por apuntarme en la dirección correcta

Puede usar el método WaitHandle.WaitOne para solicitar la propiedad de un mutex. El hilo que posee un mutex puede solicitar el mismo mutex en llamadas repetidas a WaitOne sin bloquear su ejecución. Sin embargo, el hilo debe llamar al método ReleaseMutex la misma cantidad de veces para liberar la propiedad del mutex. La clase Mutex impone la identidad del hilo, por lo que un mutex solo puede ser liberado por el hilo que lo adquirió.

+2

Su primera ejecución es mantener el mutex dos veces, pero solo lo libera una vez. Por lo tanto, lo está abandonando. –

Respuesta

19

Su problema es que mantiene el Mutex dos veces, pero solo lo libera una vez, debido a la forma en que ha arreglado mal sus declaraciones if. Su primera ejecución lo captura dos veces - en ambas declaraciones if, pero su código solo lo libera una vez.

Necesita reorganizar el if s para que solo capture el mutex una vez.

bool captured = true; 
if (!mutex.WaitOne(1000, false)) 
{ 
     Console.WriteLine("First check - some one locked the mutex"); 
     captured = false; 
} 
if (!captured && !mutex.WaitOne(3000, false)) 
{ 
     Console.WriteLine("Second check- some one locked the mutex"); 
     captured = false; 
} 
if (captured) 
{ 
     Console.WriteLine("I got the mutex"); 
     Console.WriteLine("sleeping"); 
     Thread.Sleep(3000); 
     Console.WriteLine("Awaking and Releasing mutex"); 
     mutex.ReleaseMutex(); 
} 
-2

Creo que su problema proviene de la línea using (var mutex = new Mutex(false, "mySpecialMutex")). Cuando termine el primer hilo, eliminará el objeto mutex que, en mi opinión, podría causar el error que está recibiendo.

Si es posible, sería mejor declarar el mutex como una variable de clase (estática) fuera de ese método. Luego lo instanciaría manualmente antes de iniciar sus hilos y deshacerse de ellos una vez que se hayan completado.

+0

Esto no es correcto. Los mutexes con nombre son de todo el sistema. Es la eliminación sin liberarlo lo que causa que tenga un error en lugar de nunca liberarlo. –

+0

Intenté hacer que la variable estuviera estática y que los hilos no terminaran, pero terminé con la misma excepción. – nighthawk457