【发布时间】:2019-07-19 22:50:41
【问题描述】:
lock 使用这种模式
if(Monitor.Enter(lock))
try
{
...
}
finally { Monitor.Exit(lock); } // using this style to reduce post "height"
如果我们不想无限等待,我们可以提供超时
if(!Monitor.TryEnter(lock, timeout))
throw new TimeoutException();
try
{
...
}
finally { Monitor.Exit(lock); }
我有一个场景,即方法在开始做任何事情之前必须获得多个锁。这看起来很糟糕:
if(!Monitor.TryEnter(lockA, timeout))
throw new TimeoutException();
try
{
if(!Monitor.TryEnter(lockB, timeout))
throw new TimeoutException();
try
{
if(!Monitor.TryEnter(lockC, timeout))
throw new TimeoutException();
try
{
... // more of such constructions
}
finally { Monitor.Exit(lockC); }
}
finally { Monitor.Exit(lockB); }
}
finally { Monitor.Exit(lockA); }
有问题:
看起来很难看(方法代码是缩进的,想象一下它会如何查找
lockZ),可以通过将方法代码放入另一个方法来解决。锁定是同步发生的,因此最坏的成功情况可能需要的时间略少于所有超时的总和。
有没有办法改进这种超时模式?
我正在考虑创建一个带有委托参数和锁的方法来实现类似 linq 链接(但也要并行运行锁,这是一个挑战):
Lock(lockA).Lock(lockB).Lock(lockC).Run( () => ...);
或者也许还有其他方法?
【问题讨论】:
标签: c# design-patterns timeout locking