如何在C#中为Enum类型应用InterLocked.Exchange?

vin*_*ani 17 .net c# multithreading

public enum MyEnum{Value1, Value2}  
class MyClass 
{ 
    private MyEnum _field;   
    public MyEnum Field  // added for convenience
    {
        get { return _field; }  
        set { Interlocked.Exchange(ref _field, value); // ERROR CS0452  }
    }  
} 
Run Code Online (Sandbox Code Playgroud)

可以解决:

 public enum MyEnum{Value1, Value2}  
 public class MyClass2  
 {  
   private int _field;  //change to int
   public MyEnum Field  // added for convenience
   { 
    get { return (MyEnum)_field; }
    set { System.Threading.Interlocked.Exchange(ref _field, (int)value); }
   }  
 }
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来解决这个问题?

Ste*_*eve 7

有没有更好的方法来解决这个问题?

如果你需要使用Interlocked.Exchange那么这是最好的方法,事实上我认为这是交换枚举的唯一方法.

您收到编译器错误的原因是编译器认为您要使用Exchange<T>,但T需要是一个引用类型才能使用,因为您没有使用它失败的引用类型.所以,最好的解决方法是int像你一样强制转换为一个,从而强制编译器使用非泛型Exchange(int, int).


Cor*_*sak 5

您似乎不需要Interlocked.Exchange的“交换”功能,因为您忽略了它的返回值。因此,我认为可能使您最快乐的解决方案是将_field标记为volatile:

private volatile MyEnum _field;
Run Code Online (Sandbox Code Playgroud)

  • @harold:C#中的易失性被记录为在读取和写入时造成“半栅栏”,而不是“全栅栏”。实际上,一个实现当然可以选择提供一半以上的防护,但是如果您依赖于此,那么您将依赖于一个未记录的实现细节,该细节可能会发生变化。就是说,您当然正确地注意到“易失性”和“原子测试并设定”是两个完全不同的事物。 (7认同)
  • @harold:您是否正在拆卸具有强大内存模型(例如x64或x86)的体系结构?在那些体系结构上,所有访问都已经*被视为易失性的,因此无需生成隔离。“易失性”对那些体系结构的唯一影响是防止编译器优化。如果要查看栅栏的生成,则可以在较弱的内存模型芯片(如Itanium)上拆卸。 (4认同)
  • AFAIK“易失性”并不能取代 Interlocked.Exchange!它只是确保变量不被缓存,而是直接使用。增加变量实际上需要三个操作: 1.read 2.copy 3.write Interlocked.Exchange 将所有三个部分作为单个原子操作执行 (2认同)
  • @harold:Volatile不保证C#中的顺序一致性。它保证获取和释放语义。如果您想知道C#的确切保证,我建议您阅读C#规范的相关部分。 (2认同)