我正在使用ReaderWriterLock类来锁定Quotes集合,这是一个SortedDictionary。我正在考虑使用while循环,直到线程可以获取读取器锁定,以防它被临时锁定以进行写入。第一个问题,我的测试工作正常,但这种方法有一个缺点。第二个问题,这样做的最佳/最佳实践方式是什么?
public void RequestQuote(string symbol, QuoteRequestCallback qrc)
{
// add the call back on a list and take care of it when the quote is available
while (!AcquireReaderLock(100)) Thread.Sleep(150);
if (Quotes.ContainsKey(symbol))
{
qrc(Quotes[symbol]);
rwl.ReleaseReaderLock();
}
else
{
rwl.ReleaseReaderLock();
lock (requestCallbacks)
requestCallbacks.Add(new KeyValuePair<string, QuoteRequestCallback>(symbol, qrc));
// request symbol to be added
AddSymbol(symbol);
}
}
private bool AquireReaderLock(int ms)
{
try
{
rwl.AcquireReaderLock(ms);
return true;
}
catch (TimeoutException)
{
return false;
}
}
private bool AquireWriterLock(int ms)
{
try
{
rwl.AcquireWriterLock(ms);
return true;
}
catch (TimeoutException)
{
return false;
}
}
答案 0 :(得分:2)
在使用requestCallbacks
方法锁定之前,您是否有第二段代码锁AcquireReaderLock()
?如果是这样,它就会陷入僵局。
添加循环和睡眠延迟以避免死锁在一般情况下不起作用。严格的hierarchy of lock acquisition 将在一般情况下工作。
答案 1 :(得分:2)
我不太明白你想要达到的目标。 ReaderWriterLockSlim
(我使用过)已经表现得那么简单 - 不需要额外的旋转,你只是在浪费资源。 a)如果未找到符号或更好的符号,则将R-Lock提升为W-Lock,将R和W访问分离为不同的方法。 b)不提供从受保护部分内部调用未知代码的可能性
public void RequestQuote(string pS, QuoteRequestCallback pQrc) {
Quote tQ;
// acquire/release ReadLock inside TryGet
if (TryGetQuote(pS, out tQ)) {
pQrc(tQ);
} else {
// acquire/release WriteLock inside AddQuote
// remark: I left the other collection
// out since it seems unrelated to the actual problem
AddQuote(new KeyValuePair(...)); // as above
}
}