Interlocked.Exchange
是你在找什么对于。不幸的是,如上所述,你不能用它与bool
,这是一个耻辱。一种替代方法是使用this answer中指出的int
过载。
该解决方案的“幻数” -ness一直困扰个人我一点点。但有你就可以说,否则就像一个bool
引用类型的方式:
public sealed class RefBool
{
public static implicit operator bool(RefBool value)
{
return value != null;
}
public static implicit operator RefBool(bool value)
{
return value ? RefBool.True : RefBool.False;
}
public static bool operator true(RefBool value)
{
return value != null;
}
public static bool operator false(RefBool value)
{
return value == null;
}
public static readonly RefBool True = new RefBool();
public static readonly RefBool False = null;
private RefBool()
{
}
}
现在,您的类可以是这样的:
public class Syncer
{
private RefBool mIsSyncInProgress = false;
public void SyncData()
{
if (Interlocked.Exchange(ref mIsSyncInProgress, true))
{
return;
}
// Sync data...
// It is enough that one thread is syncing data
Interlocked.Exchange(ref mIsSyncInProgress, false);
}
}
我觉得这更容易在使用场所阅读。我不觉得这个解决方案是完美的,因为RefBool
类有点奇怪。
你应该注意到我用null
的真实状态。这是为了确保类型RefBool
的变量只能是true
或false
。如果我用了两个不同的实例来表示true
和false
,然后RefBool
也可能是null
,这将是一个不确定的状态。
这样做的缺点是,ToString
不正确的工作(这就是为什么我没有打扰覆盖它)。
你尝试过这么远吗? – ArgusMagnus
我写的代码不是线程安全的 – Uros
不熟悉C#中的原子操作,但是'Interlocked.Exchange'? https://msdn.microsoft.com/en-us/library/bb337971(v=vs.110).aspx – chris