是否有可能检测到同一个线程是否试图释放锁定?
我们在代码中有很多地方看起来像:
try
{
try
{
if(!Monitor.TryEnter(obj, 2000))
{
throw new Exception("can not lock");
}
}
finally
{
Monitor.Exit(obj);
}
}
catch
{
//Log
}
上面的代码非常简化,实际上Enter和Exit语句位于自定义对象(lock manager)中.
问题是,在该结构中,我们在尝试“退出”时遇到SynchronizationLockException,因为它看起来像是没有成功锁定的线程,试图最终释放.
所以问题是,我怎么知道创建Monitor.Exit的线程是否与Monitor.Enter的线程相同?
我以为我可以使用CurrentThread.Id同步进入和退出,但我不确定它是否“足够安全”.
解决方法:
正如你认为在try-catch中调用Monitor.Exit是’durty'(脏?),这是一个非常简单的想法,试图“把二十年代带走”.锁是可重入的同一个线程,如果一个线程成功获取,在它释放之前,另一个线程的尝试将失败.所以你可以考虑这样的事情:
public void Exit(object key) {
if(!IsActive) {
return;
}
if(LockDictionary.ContainsKey(key)) {
var syncObject=LockDictionary[key];
if(Monitor.TryEnter(syncObject.SyncObject, 0)) {
SetLockExit(syncObject);
Monitor.Exit(syncObject.SyncObject);
Monitor.Exit(syncObject.SyncObject);
}
}
}
我们调用Monitor.Exit两次,因为我们将它锁定两次,一次在代码外部,一次在这里.