首先-大多数类将永远不需要是线程安全的。使用YAGNI:仅当您知道实际上将要使用它(并对其进行测试)时,才应用线程安全性。
对于方法级的东西,有[MethodImpl]
:
[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}
这也可以用于访问器(属性和事件):
private int i;
public int SomeProperty
{
[MethodImpl(MethodImplOptions.Synchronized)]
get { return i; }
[MethodImpl(MethodImplOptions.Synchronized)]
set { i = value; }
}
请注意,默认情况下,类似字段的事件是同步的,而自动实现的属性则不是:
public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized
就我个人而言,我不喜欢使用MethodImpl
锁this
或typeof(Foo)
-这是违反最佳做法的实现。首选选项是使用您自己的锁:
private readonly object syncLock = new object();
public void SomeMethod() {
lock(syncLock) { /* code */ }
}
请注意,对于类似字段的事件,锁定实现取决于编译器。在较旧的Microsoft编译器中,它是lock(this)
/ lock(Type)
-但是,在较新的编译器中,它使用Interlocked
更新-因此具有线程安全性而没有令人讨厌的部分。
这允许更精细的使用,并允许使用Monitor.Wait
/ Monitor.Pulse
etc在线程之间进行通信。
相关的博客条目(后来重新访问)。