2010-10-24 23 views
18

Tengo una aplicación multiproceso que escribe en un archivo xml de configuración utilizando un método estático. Quiero evitar que el archivo se actualice dos veces al mismo tiempo (causando accesos/excepción de escritura).Bloquear() en un método estático

¿Cómo puedo hacer eso?

Esto no funciona:

namespace Program 
{ 
    public class Settings 
    { 
     private static void SetSettingsValue (string settings, string value) 
     { 
      // make this thread safe to avoid writing to a locked settings xml file 
      lock (typeof(Settings)) 
      { 
       //write data to xml file 
      } 
     } 
    } 
} 
+1

¿Desea deshacerse de su archivo XML correctamente (es decir, mediante 'using')? ¿Puedes compartir más código? Además, para los métodos estáticos, debe "bloquear" en objetos estáticos privados, no en un tipo. Consulte http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx –

Respuesta

33

El concepto de lock() es usar un objeto existente que puede hacer referencia y usar para controlar si se concede el acceso.

static object SpinLock = new object(); 

lock(SpinLock) 
{ 
    //Statements 
} 

Cuando la ejecución sale de la cerradura() bloquear la referencia se libera y cualesquiera otros hilos esperar a ejecutar el bloque de código puede proceder (uno a la vez, por supuesto).

+2

Tenga en cuenta que no puede cambiar la referencia de SpinLock dentro de la propia instrucción lock(). El objeto utilizado para el bloqueo necesita ser accesible por todos los hilos que necesitan ejecutar el código y no puede cambiar la referencia cada vez o los hilos nunca se bloquearán entre sí y usted tendrá contención de recursos/conflictos. –

37

Debe crear un objeto de bloqueo separado, estático y usar eso. NO USE UNA CADENA Las cadenas se internan automáticamente y solo habrá una instancia de cada cadena declarada mediante programación, por lo que no puede garantizar el acceso exclusivo al bloqueo.

usted debe hacer esto:

public class A { 
    private static Object LOCK = new Object(); 

    private static void foo() { 
     lock(LOCK) { 
      // Do whatever 
     } 
    } 
} 

(La sintaxis puede ser incorrecta, soy una persona de Java en su mayoría, pero las mismas reglas sobre el bloqueo y cadena internar aplica a C#)

La expresión lock impone un bloqueo de exclusión mutua: solo un hilo puede bloquear cualquier objeto en particular a la vez. Si un segundo hilo llama al foo, bloqueará hasta que el primer hilo haya salido del bloque de bloqueo.

Mensajes para llevar a casa: para un método estático de bloqueo en una variable estática privada. No bloquee las cadenas o typeof (...) porque no puede garantizar que nadie más esté usando ese objeto. Siempre asegúrate de que un objeto que conoces no haya sido tocado por otra persona haciéndolo privado y actualizándolo.

+3

Esta es la mejor respuesta en toda la discusión. Porque Cameron fue lo suficientemente inteligente como para especificar que la cerradura es privada para la clase. –

+0

También debería ser lo que sea el equivalente de C# de 'final', pero no soy C#, así que no estoy seguro de qué es eso. Si C# tiene 'const' de estilo C++, entonces creo que cambiaré de Java :) –

+0

Adivina no: http://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and- readonly –

Cuestiones relacionadas