我有物品,他们得到锁。我想测试他们是否被锁定而没有获得锁定。我的想法是TryEnter()
,如果Exit()
我必须true
才能正确检查锁定。
似乎是一个非常基本的问题,它是如何完成的?
答案 0 :(得分:22)
当您查看锁定 锁定时,您可以获得哪些可能的信息?当您根据该信息做出决定时,可能已经锁定了。
答案 1 :(得分:3)
因为lock语句等同于:
System.Threading.Monitor.Enter(x);
try {
...
}
finally {
System.Threading.Monitor.Exit(x);
}
你能这样做吗?
bool ObjectWasUnlocked(object x)
{
if(System.Threading.Monitor.TryEnter(x))
{
System.Threading.Monitor.Exit(x);
return true;
}
else
{
return false;
}
}
请注意,我正在命名此函数“Object Unlocked”,而不是“ObjectIsUnlocked”。无法保证在函数返回时它仍然会被解锁。
答案 2 :(得分:3)
在尝试审核我的代码以进行正确锁定时,我想知道同样的事情。我想出了一个使用第二个线程的方法。如果锁可用于调用线程,但第二个线程不可用,则必须由第一个线程保持。
/// <summary>
/// Utiltity for checking if a lock has already been acquired.
/// WARNING: This test isn't actually thread-safe,
/// it's only really useful for unit tests
/// </summary>
private static bool ObjectIsAlreadyLockedByThisThread(object lockObject)
{
if (!Monitor.TryEnter(lockObject))
{
// another thread has the lock
return false;
}
Monitor.Exit(lockObject);
bool? LockAvailable = null;
var T = new Thread(() =>
{
if (Monitor.TryEnter(lockObject))
{
LockAvailable = true;
Monitor.Exit(lockObject);
}
else
{
LockAvailable = false;
}
});
T.Start();
T.Join();
return !LockAvailable.Value;
}
// Tests:
public static void TestLockedByThisThread()
{
object MyLock = new object();
lock (MyLock)
{
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
Debug.WriteLine(WasLocked); // prints "True"
}
}
public static void TestLockedByOtherThread()
{
object MyLock = new object();
var T = new Thread(() =>
{
lock (MyLock)
{
Thread.Sleep(TimeSpan.FromSeconds(2));
}
});
T.Start();
Thread.Sleep(TimeSpan.FromSeconds(1));
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
T.Join();
Debug.WriteLine(WasLocked); // prints "False"
}
public static void TestNotLocked()
{
object MyLock = new object();
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
Debug.WriteLine(WasLocked); // prints "False"
}
我不会在生产代码中使用它 - 这种竞争条件可能会爆炸。但是,我的单元测试大多是单线程的,所以这很有用。
答案 3 :(得分:1)