2009-03-13 15 views
8

¿No sería esto exagerado y solo uno de estos es necesario? He buscado y encontrado diferentes publicaciones sobre Exclusión mutua y bloqueos en C# here y here.

Ejemplo:
En nuestra aplicación, tenemos una función que hace girar múltiples hilos de reconexión y dentro de este hilo usamos un Mutex y un lock. ¿No bloquearía lock el acceso a esta sección de código y evitaría que connect fuera actualizado por algún otro hilo?Deberían usarse bloqueos y mutexes en C# juntos

bool connect = false; 
Mutex reconnectMutex = new Mutex(false, "Reconnect_" + key); 

try 
{ 
    lock(site) 
    { 
     if(site.ContainsKey(key)) 
     { 
     siteInfo = (SiteInfo)site[key]; 
     if(reconnectMutex.WaitOne(100, true)) 
     { 
      connect = true; 
     } 
     } 
    } 

    if (connect) 
    { 
     // Process thread logic 
    } 
} 
catch 
{} 

reconnectMutex.ReleaseMutex(); 

Más información:
Esto es en un servicio Web ASP.NET no se ejecuta en un jardín Web.

Respuesta

11

Ese Mutex (porque tiene un nombre) detendrá cualquier proceso en la misma máquina accediendo a él, mientras que el bloqueo solo detendrá otros hilos en el mismo proceso. No puedo ver en ese ejemplo de código por qué necesitarías ambos tipos de bloqueo. Parece una buena práctica mantener el bloqueo simple durante un corto período de tiempo, pero luego el mutex interproceso mucho más pesado se bloquea durante un período probablemente más largo (aunque superpuesto). Sería más simple usar el mutex. Y tal vez para averiguar si un bloqueo entre procesos es realmente necesario. Por supuesto, catch {} es absolutamente incorrecto utilizar en ese escenario. Debe usar finally { /* release mutex */ }. Ellos son muy diferentes. La captura se tragará mucho más tipos de excepción de lo que debería, y también causará finalmente anidado manipuladores para ejecutar en respuesta a las excepciones de bajo nivel, como la corrupción de memoria, acceso violación, etc. Así que en lugar de:

try 
{ 
    // something 
} 
catch 
{} 

// cleanup 

usted debe tener:

try 
{ 
    // something 
} 
finally 
{ 
    // cleanup 
} 

Y si hay excepciones específicas que puede recuperarse de, usted podría atraparlos:

try 
{ 
    // something 
} 
catch (DatabaseConfigurationError x) 
{ 
    // tell the user to configure the database properly 
} 
finally 
{ 
    // cleanup 
} 
+0

tiene que ser nombrado en consecuencia para ser específico de la máquina, sin embargo. –

+0

Buen punto, espero haber aclarado eso en la primera oración. –

+0

¿Estás diciendo que debería eliminar la declaración catch y reemplazarla por una finalmente? –

3

"bloquear" básicamente es sólo una azúcar sintáctica para Montor. Entrar/Salir. Mutex es un bloqueo multiproceso.

Tienen un comportamiento muy diferente. No hay nada de malo en usar ambos en la misma aplicación o métodos, ya que están diseñados para bloquear cosas diferentes.

Sin embargo, en tu caso, creo que es mejor que busques en Semaphore and Monitor. No parece que necesite bloquear procesos, por lo que probablemente sean una mejor opción en esta situación.

1

No proporcionaste información suficiente para realmente responder a esto. Como ya dijo Earwicker, un Mutex le permite tener una sincronización entre los procesos. Por lo tanto, si tiene dos instancias de la misma aplicación en ejecución, puede serializar el acceso. Puede hacer esto, por ejemplo, al usar recursos externos.

Ahora que bloquea en el sitio protege el sitio de acceso por otros hilos en el mismo proceso. Esto podría ser nessecary dependiendo de lo que otros métodos/hilos estén haciendo. Ahora bien, si este es el único lugar donde se está bloqueando el sitio, entonces sí, creo que es excesivo.

2

Como han señalado otros, el Mutex bloquea los procesos y el bloqueo local (Monitor) bloquea solo los hilos propiedad del proceso actual. Sin embargo ...

El código que mostró tiene un error bastante grave.Parece que está liberando el Mutex incondicionalmente al final (es decir, reconnectMutex.ReleaseMutex()), pero el Mutex solo se adquiere si site.ContainsKey() devuelve true.

Así que si site.ContainsKey devuelve false, liberando el Mutex se lanzará ApplicationException porque el hilo de llamada no posee el Mutex.

+0

Gracias - Encontré ese error después de publicar esto. No pude entender por qué la aplicación se estaba cerrando, ese era el problema. –

Cuestiones relacionadas