我试图编写一个线程安全的方法(每个对象实例只能调用一次)。如果之前已调用过异常,则应抛出异常。
我提出了两种解决方案。他们都正确吗?如果没有,那他们怎么了?
lock
一起使用:public void Foo()
{
lock (fooLock)
{
if (fooCalled) throw new InvalidOperationException();
fooCalled = true;
}
…
}
private object fooLock = new object();
private bool fooCalled;
Interlocked.CompareExchange
一起使用:public void Foo()
{
if (Interlocked.CompareExchange(ref fooCalled, 1, 0) == 1)
throw new InvalidOperationException();
…
}
private int fooCalled;
如果我没记错的话,此解决方案的优点是免锁(在我的情况下这似乎无关紧要),并且需要较少的私有(private)字段。
如果有更好的方法,我也欢迎公开征询意见,最好选择哪种解决方案,并提出进一步的建议。
最佳答案
您的Interlocked.CompareExchange
解决方案看起来最好,并且(如您所说)是无锁的。它也比其他解决方案复杂得多。锁非常重,而CompareExchange
可以编译为单个CAS cpu指令。我说去那一个。
关于c# - 如何: Write a thread-safe method that may only be called once?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9514411/