线程安全实现一次性方法

本文关键字:方法 一次性 实现 安全 线程 | 更新日期: 2023-09-27 18:21:56

我有一个方法,它必须被调用不超过一次,例如Dispose。现在,我意识到它是下一个:

private bool _isAlive = true;
public void Dispose()
{
    if (this._isAlive)
    {
        this._isAlive = false;
        //Do Something
    }
}

但是它不是线程安全的,因为在编译和将标志_isAlive设置为false之间存在间隙。因此,可能有多个线程执行//Do Something代码。

它有线程安全的变体吗?

线程安全实现一次性方法

使用(根据注释更新):

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 */ } 
}

使用MethodImpAttribute是IMHO最简单的方法。

  public void Dispose()
  {
      if (isAlive && ShouldDispose())
      {
          //Your code here
      }
  }
  [MethodImplAttribute(MethodImplOptions.Synchronized)]
  private bool ShouldDispose()
  {
       if (isAlive)
       {
            isAlive = false;
            return true;
       }
       return false;
  }