我在锁定集合中的项目时遇到问题 - 特别是 ConcurrentDictionary。
我需要接受一条消息,在字典中查找该消息,然后对其进行长时间的扫描。由于程序占用大量内存,扫描后对象返回true如果他们认为现在是删除它的好时机(我通过将其从词典中删除来做到这一点)。但是,另一个线程可能会在相似的时间出现并尝试在删除后立即访问同一对象。这是我的第一次尝试:
string dictionaryKey = myMessage.someValue;
DictionaryObject currentObject = myConcurrentDictionary.GetOrAdd(dictionaryKey, new DictionaryObject());
// we can be interrupted here
lock (currentObject)
{
//KeyNotFoundException is possible on line below
if (myConcurrentDictionary[dictonaryKey].scan(myMessage)) // Scans the message - returns true if the object says its OK to remove it from the dictionary
{
DictionaryObject temp; // It's OK to delete it
if (!queuedMessages.TryRemove(ric, out temp)) // Did delete work?
throw new Exception("Was unable to delete a DictionaryObject that just reported it was ok to delete it");
}
}
但是,上述方法不起作用 - 一个线程可能会在另一个线程尝试访问字典中的对象之前从字典中删除该对象。读完之后lock 是 Monitor.Enter 和 Monitor.Exit 的简写 http://www.albahari.com/threading/part2.aspx#_Locking,我尝试过这个:
string dictionaryKey = myMessage.someValue;
Monitor.Enter(GetDictionaryLocker);
DictionaryObject currentObject = myConcurrentDictionary.GetOrAdd(dictionaryKey, new DictionaryObject());
// we can be interrupted here
lock (currentObject)
{
Monitor.Exit(GetDictionaryLocker);
//KeyNotFoundException is still possible on line below
if (myConcurrentDictionary[dictonaryKey].scan(myMessage)) // Scans the message - returns true if the object says its OK to remove it from the dictionary
{
DictionaryObject temp; // It's OK to delete it
if (!queuedMessages.TryRemove(ric, out temp)) // Did delete work?
throw new Exception("Was unable to delete a DictionaryObject that just reported it was ok to delete it");
}
}
两种方式都可能导致密钥未找到异常当尝试在字典中查找对象时。
有谁知道我如何找到我想要锁定的对象,然后在不被中断的情况下锁定它?抱歉 - 我是并发新手,感到非常困惑!
Thanks,
Frederik