如何从其他线程锁定c#中的方法的一部分? 我的意思是如果其中一个线程在这里,然后退出... 例如:
if(threads[0].WasHere)
{
return;
}
答案 0 :(得分:6)
一种有效的方式是互锁交换;通过在工作期间将一些令牌字段设置为非默认值,其他线程可以检查并退出。例如:
private int hazWorker; // = 0 - put this at the scope you want to protect
然后:
// means: atomically set hazWorker to 1, but only if the old value was 0, and
// tell me what the old value was (and compare that result to 0)
if(Interlocked.CompareExchange(ref hazWorker, 1, 0) != 0) {
return; // someone else has the conch
}
try {
// your work here
} finally {
Interlocked.Exchange(ref hazWorker, 0); // set it back to default
}
答案 1 :(得分:5)
您可以将Monitor.TryEnter用于此目的。
if(!Monitor.TryEnter(someLock))
{
return;
}
try
{
//Critical region
}
finally
{
Monitor.Exit(someLock);
}
或者更可靠的方式与粗鲁线程中止(marc在评论中建议)
bool lockTaken = false;
try
{
Monitor.TryEnter(someLock, ref lockTaken);
if (lockTaken)
{
//Critical region
}
}
finally
{
if(lockTaken) Monitor.Exit(someLock);
}
请注意,这不会检查threads[0]
是否仍然有效,而是检查是否有任何其他线程位于关键区域中。如果是这样,它将退出该方法。
答案 2 :(得分:2)
你可以使用bool值 - 分配它" false"默认情况下,然后第一个线程将其设置为" true"。然后这段代码看起来像这样:
if (!alreadyExecuted)
{
// ...
alreadyExecuted = true;
}
我还会把代码放在一个锁中,以确保只有一个线程在执行时(处理任何可能的竞争条件),如下所示。
lockVariable是一个更衣室变量,它可以是任何引用类型,例如。 object lockVariable = new object();
lock (lockVariable)
{
if (!alreadyExecuted)
{
// ...
alreadyExecuted = true;
}
}