Primero: la mayoría de las clases nunca necesitarán ser seguras para subprocesos. Use YAGNI : solo aplique seguridad de hilo cuando sepa que realmente lo va a usar (y probarlo).
Para las cosas de nivel de método, hay [MethodImpl]
:
[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}
Esto también se puede usar en accesores (propiedades y eventos):
private int i;
public int SomeProperty
{
[MethodImpl(MethodImplOptions.Synchronized)]
get { return i; }
[MethodImpl(MethodImplOptions.Synchronized)]
set { i = value; }
}
Tenga en cuenta que los eventos similares a campos se sincronizan de manera predeterminada, mientras que las propiedades implementadas automáticamente no lo son :
public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized
Personalmente, no me gusta la implementación MethodImpl
ya que se bloquea this
o typeof(Foo)
, lo que va en contra de las mejores prácticas. La opción preferida es usar sus propios bloqueos:
private readonly object syncLock = new object();
public void SomeMethod() {
lock(syncLock) { /* code */ }
}
Tenga en cuenta que para eventos de tipo campo, la implementación de bloqueo depende del compilador; en los compiladores de Microsoft más antiguos es un lock(this)
/ lock(Type)
, sin embargo, en los compiladores más recientes usaInterlocked
actualizaciones, por lo que es seguro para subprocesos sin las partes desagradables.
Esto permite un uso más granular y permite el uso de Monitor.Wait
/ Monitor.Pulse
etc para comunicarse entre subprocesos.
Una entrada de blog relacionada (luego revisada ).