我正在尝试使用Interlocked.CompareExchange这个枚举:
public enum State {
Idle,
Running,
//...
}
Run Code Online (Sandbox Code Playgroud)
以下代码无法编译,但这就是我想要做的:
if (Interlocked.CompareExchange(ref state, State.Running, State.Idle) != State.Idle) {
throw new InvalidOperationException("Unable to run - not idle");
}
Run Code Online (Sandbox Code Playgroud)
当然我可以使用int而不是枚举并使用属性:
private int state = (int)State.Idle;
public State { get { return (State)state; } }
Run Code Online (Sandbox Code Playgroud)
然后将枚举转换为int:
if (Interlocked.CompareExchange(ref state, (int)State.Running, (int)State.Idle) != (int)State.Idle) {
throw new InvalidOperationException("Unable to run - not idle");
}
Run Code Online (Sandbox Code Playgroud)
但有没有更好的方法来做到这一点?
System.Threading.Interlocked.CompareExchange operator提供了Compare-And-Swap操作的原子(因此是线程安全的)C#实现.
例如,int i = 5; Interlocked.CompareExchange(ref i, 10, 5);在此命令之后,int i将具有值= 10.并且比较和交换以原子方式发生(单个操作).
当我尝试将其与类实例一起使用时,比较失败并且不交换值.
public class X
{
public int y;
public X(int val) { y = val; }
}
Run Code Online (Sandbox Code Playgroud)
现在当我这样做
X a = new X(1);
X b = new X(1);
X c = new X(2);
Interlocked.CompareExchange<X>(ref a, c, b);
Run Code Online (Sandbox Code Playgroud)
比较和Exchange操作失败.所以,我将X类的Equals和==运算符重写为
public override bool Equals(object obj) { return y == ((X) obj).y; }
Run Code Online (Sandbox Code Playgroud)
所以,现在我得到Interlocked.Equals(a,b)了true,但CompareExchange操作仍然失败.
有没有办法做到这一点?我想比较两个类实例,并根据比较为其中一个指定一个值.