Esta es una pregunta de detalle para C#.Seguridad de hilo C# con get/set
Supongamos que tengo una clase con un objeto, y ese objeto está protegido por una cerradura:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
return property;
}
set {
property = value;
}
}
Quiero un hilo de votación para ser capaz de consultar esa propiedad. También quiero que el subproceso actualice propiedades de ese objeto ocasionalmente, y algunas veces el usuario puede actualizar esa propiedad, y el usuario desea poder ver esa propiedad.
¿El siguiente código bloqueará correctamente los datos?
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
lock (mLock){
return property;
}
}
set {
lock (mLock){
property = value;
}
}
}
Por 'adecuadamente', lo que quiero decir es, si quiero llamar
MyProperty.Field1 = 2;
o lo que sea, será el campo puede bloquear mientras hago la actualización? Es la configuración realizada por el operador igual dentro del alcance de la función 'get', o la función 'get' (y por lo tanto el bloqueo) terminará primero, y luego se llamará a la configuración, y luego 'set', evitando así ¿La cerradura?
Editar: Dado que aparentemente esto no funciona, ¿qué será? ¿Necesito hacer algo como:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
MyObject tmp = null;
lock (mLock){
tmp = property.Clone();
}
return tmp;
}
set {
lock (mLock){
property = value;
}
}
}
que más o menos solo se asegura de que sólo tengo acceso a una copia, lo que significa que si yo fuera a tener dos hilos llaman un 'get', al mismo tiempo, cada uno comenzaría con el mismo valor de Field1 (¿verdad?). ¿Hay alguna forma de hacer bloqueo de lectura y escritura en una propiedad que tenga sentido? ¿O debería limitarme a bloquear secciones de funciones en lugar de los datos en sí?
Solo para que este ejemplo tenga sentido: MyObject es un controlador de dispositivo que devuelve el estado de forma asincrónica. Le envío comandos a través de un puerto serie, y luego el dispositivo responde a esos comandos en su propio momento. En este momento, tengo un hilo que lo sondea por su estado ("¿Sigues ahí? ¿Puedes aceptar comandos?"), Un hilo que espera respuestas en el puerto serial ("Acabo de recibir la cadena de estado 2, todo está bien"), y luego el subproceso UI que toma otros comandos ("El usuario quiere que hagas esto") y publica las respuestas del controlador ("Acabo de hacer el trabajo, ahora actualizo la interfaz de usuario con eso"). Es por eso que quiero asegurar el objeto en sí mismo, en lugar de los campos del objeto; eso sería una gran cantidad de bloqueos, a, y b, no todos los dispositivos de esta clase tienen el mismo comportamiento, solo el comportamiento general, así que tendría que codificar muchos diálogos individuales si individualizara los bloqueos.
De acuerdo. Proporcioné una solución de muestra para lo que está preguntando en respuesta a una pregunta de Singleton http://stackoverflow.com/questions/7095/is-the-c-static-constructor-thread-safe/7105#7105 – Zooba
sí, me ' Probablemente vaya con bloquear el objeto como lo ha descrito. Gracias. – mmr
Buen punto, sin embargo, si tenía un 'MyProperty' llamado' p' y llamado dos hilos a la vez: 'p = new MyObject (12)' y 'p = new MyObject (5)' entonces * este * acceso estaría sincronizado . Sin embargo, el miembro 'Field1' * * nunca * estaría bloqueado. Estoy bastante seguro de que esto es lo que dices, solo trato de entenderlo por mí mismo. – Snoopy