Erstens: Die meisten Klassen müssen niemals threadsicher sein. Verwenden Sie YAGNI : Wenden Sie Thread-Sicherheit nur an, wenn Sie wissen, dass Sie es tatsächlich verwenden werden (und testen Sie es).
Für die Sachen auf Methodenebene gibt es [MethodImpl]
:
[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}
Dies kann auch für Accessoren (Eigenschaften und Ereignisse) verwendet werden:
private int i;
public int SomeProperty
{
[MethodImpl(MethodImplOptions.Synchronized)]
get { return i; }
[MethodImpl(MethodImplOptions.Synchronized)]
set { i = value; }
}
Beachten Sie, dass feldartige Ereignisse werden standardmäßig synchronisiert, während automatisch implementierte Eigenschaften sind nicht :
public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized
Persönlich mag ich die Implementierung nicht, MethodImpl
da sie sperrt this
oder typeof(Foo)
- was gegen Best Practice verstößt. Die bevorzugte Option ist die Verwendung eigener Schlösser:
private readonly object syncLock = new object();
public void SomeMethod() {
lock(syncLock) { /* code */ }
}
Beachten Sie, dass bei feldähnlichen Ereignissen die Sperrimplementierung vom Compiler abhängt. In älteren Microsoft-Compilern ist es ein lock(this)
/ lock(Type)
- in neueren Compilern werden jedochInterlocked
Updates verwendet - also threadsicher ohne die unangenehmen Teile.
Dies ermöglicht eine detailliertere Verwendung und die Verwendung von Monitor.Wait
/ Monitor.Pulse
etc für die Kommunikation zwischen Threads.
Ein verwandter Blogeintrag (später überarbeitet ).