我有一个方法,必须调用不超过一次,例如Dispose
。现在,我意识到它是下一个:
private bool _isAlive = true;
public void Dispose()
{
if (this._isAlive)
{
this._isAlive = false;
//Do Something
}
}
但它不是线程安全的,因为comprasion和设置标志_isAlive
之间存在差距为false。因此,可能有多个线程执行//Do Something
代码。
是否有线程安全的变体?
答案 0 :(得分:5)
使用(根据评论更新):
private long _isSomeMethodExecuted = 0;
public void Dispose()
{
if ( Interlocked.Read ( ref this._isSomeMethodExecuted ) != 0 )
return;
if (Interlocked.Increment (ref this._isSomeMethodExecuted) == 1) //check if method is already executed
{
//Main code of method
}
// leave the decrement out - this leads to
// this method being callable exactly once as in the lifetime of the object
// Interlocked.Decrement (ref this._isSomeMethodExecuted);
}
参考http://msdn.microsoft.com/en-us/library/zs86dyzy.aspx
更新(根据@LukeH的评论):
单个CompareExchange
电话更简单/更好:
public void Dispose()
{
if (Interlocked.CompareExchange(ref _isSomeMethodExecuted, 1, 0) == 0)
{ /* main code of method */ }
}
答案 1 :(得分:0)
使用MethodImpAttribute是恕我直言的最简单方法。
public void Dispose()
{
if (isAlive && ShouldDispose())
{
//Your code here
}
}
[MethodImplAttribute(MethodImplOptions.Synchronized)]
private bool ShouldDispose()
{
if (isAlive)
{
isAlive = false;
return true;
}
return false;
}