A menudo, cuando quiero una clase que es seguro para subprocesos, hago algo como lo siguiente:¿Es este un buen diseño para crear clases Thread-Safe en C#?
public class ThreadSafeClass
{
private readonly object theLock = new object();
private double propertyA;
public double PropertyA
{
get
{
lock (theLock)
{
return propertyA;
}
}
set
{
lock (theLock)
{
propertyA = value;
}
}
}
private double propertyB;
public double PropertyB
{
get
{
lock (theLock)
{
return propertyB;
}
}
set
{
lock (theLock)
{
propertyB = value;
}
}
}
public void SomeMethod()
{
lock (theLock)
{
PropertyA = 2.0 * PropertyB;
}
}
}
Funciona, pero es muy detallado. Algunas veces, incluso creo un objeto de bloqueo para cada método y propiedad, creando más detalle y complejidad.
Sé que también es posible bloquear clases utilizando el atributo de Sincronización, pero no estoy seguro de qué tan bien se escala, ya que a menudo espero tener cientos de miles, sino millones, de instancias de seguridad de subprocesos objetos. Este enfoque crearía un contexto de sincronización para cada instancia de la clase, y requiere que la clase se derive de ContextBoundObject y, por lo tanto, no pueda derivarse de ninguna otra cosa, ya que C# no permite la herencia múltiple, que es un show stopper en muchos casos.
Editar: Como varios de los que respondieron han enfatizado, no hay un diseño de clase de subprocesos "de bala de plata". Solo trato de entender si el patrón que uso es una de las mejores soluciones. Por supuesto, la mejor solución en cualquier situación particular depende del problema. Varias de las respuestas a continuación contienen diseños alternativos que deben considerarse.
Editar: Además, hay más de una definición de seguridad de subprocesos. Por ejemplo, en mi aplicación anterior, el siguiente código no sería seguro para subprocesos:
var myObject = new ThreadSafeClass();
myObject.PropertyA++; // NOT thread-safe
Entonces, ¿la definición de clase superior representan un buen enfoque? Si no, ¿qué recomendarías para un diseño con un comportamiento similar que sería seguro para subprocesos para un conjunto similar de usos?
Busque primero: http://stackoverflow.com/search?q=What+is+la+máxima+práctica+para+crear+Thread-Safe+Classes+en+C%23 –
Hm. En su código, usa el mismo objeto de bloqueo para leer PropertyA y PropertyB. Eso significa que un hilo que lea PropertyA bloqueará a otro tratando de leer PropertyB hasta que se complete el primer hilo. ¿Es eso lo que quieres? Si esta fuera mi clase, crearía un casillero de lectura separado para cada comprador y luego los instaladores también deben respetar ese bloqueo. Vea una respuesta a continuación. –
Acabo de descalificarlo porque no hay una sola forma de producir una clase segura para subprocesos. Cualquier respuesta a esta pregunta corre el riesgo de dar la impresión equivocada a futuros lectores. –