Po pierwsze - większość klas nigdy nie musi być bezpieczna dla wątków. Używaj YAGNI : stosuj zabezpieczenie wątków tylko wtedy, gdy wiesz, że faktycznie zamierzasz go użyć (i przetestować).
Dla rzeczy na poziomie metod jest [MethodImpl]:
[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}
Można tego również użyć w akcesoriach (właściwościach i zdarzeniach):
private int i;
public int SomeProperty
{
[MethodImpl(MethodImplOptions.Synchronized)]
get { return i; }
[MethodImpl(MethodImplOptions.Synchronized)]
set { i = value; }
}
Pamiętaj, że zdarzenia podobne do pól są domyślnie synchronizowane, a właściwości zaimplementowane automatycznie nie są :
public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized
Osobiście nie lubię implementacji, MethodImplponieważ blokuje thislub typeof(Foo)- co jest sprzeczne z najlepszymi praktykami. Preferowaną opcją jest użycie własnych zamków:
private readonly object syncLock = new object();
public void SomeMethod() {
lock(syncLock) { /* code */ }
}
Należy zauważyć, że w przypadku zdarzeń podobnych do pola implementacja blokowania zależy od kompilatora; w starszych kompilatorach Microsoft jest to lock(this)/ lock(Type)- jednak w nowszych kompilatorach używaInterlocked aktualizacji - więc jest bezpieczne dla wątków bez nieprzyjemnych części.
Pozwala to na bardziej szczegółowe użycie i umożliwia użycie Monitor.Wait/ Monitor.Pulseetc do komunikacji między wątkami.
Powiązany wpis na blogu (później ponownie odwiedzony ).