我有一个方法Test
,它可以从许多线程中执行,并且我不想在方法已经执行时锁定要执行它们的所有线程。我的想法是在执行活动时创建易失性isProcessing
并将其设置为true
。
但是我不知道C#内存模型,也无法理解其他线程何时会看到isProcessing
的新值。它会在设置isProcessing
值后立即执行还是仅在退出lock
部分后立即执行?
代码示例:
private volatile bool isProcessing = false;
private void Test()
{
if (isProcessing) return;
lock(this){
try{
isProcessing = true;
//do something
}
finally{
isProcessing = false;
}
}
}
答案 0 :(得分:1)
这是使用两个单独的锁执行此操作的方法。请注意,锁定可能对其他呼叫站点可见的对象不是一种好习惯。
private bool isProcessing = false;
private object readLock = new object();
private object processingLock = new object();
private void Test()
{
Monitor.Enter(readLock);
if (isProcessing)
{
Monitor.Exit(readLock);
return;
}
lock (processingLock)
{
isProcessing = true;
Monitor.Exit(readLock);
try
{
//do something
}
finally
{
isProcessing = false;
}
}
}
一个更简单的解决方案是使用Mutex,而不是使用Monitors。
Mutex processingMutex = new Mutex(false);
private void Test2()
{
if (!processingMutex.WaitOne(0))
{
return;
}
try
{
//do processing
}
finally
{
processingMutex.ReleaseMutex();
}
}
Mutex还可以通过将WaitOne的参数设置为非零值来使您短暂等待其他线程是否结束。