ConcurrentDictionary和线程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ConcurrentDictionary和线程相关的知识,希望对你有一定的参考价值。
我在IIS应用程序池中有一个WCF服务。 WCF服务的方法接收JSON中的一些数据,如{“object”:“someobject”,“payload”:[int key]}。 对于每个请求,我运行新线程来使用密钥。 关键是添加到ConcurrentDictionary并锁定ConcurrentDictionary的值。 这样做的目的是:只有一个密钥可以运行一次,例如: 线程1 - 使用键1运行 线程2 - 使用键2运行 线程3 - 线程1中的等待锁定 但是当我从ConcurrentDictionary中删除键时,另一个线程已经通过键获取值并使用它。怎么避免这个?附近的线程处理程序示例
static ConcurrentDictionary<string, object> taskDictionary=new ConcurrentDictionary<string, object>();
static void ThreadHandler(int key)
{
try
{
var lockElem=taskDictionary.GetOrAdd(key, new object());
//Thread 3 get value by key 1 here and waits here
lock(lockElem)
{
taskDictionary.TryRemove(key, out _);
// but Thread 1 removes value by key 1 here
//and Thread 4 can add value in Dictionary with same key (key 1)
}
}
finally
{
}
}
在这种情况下出现问题:线程1使用GetOrAdd,然后使用锁定值,然后使用TryRemove。在这个时候,线程3.使用GetOrAdd,取值,但是等待来自线程1的锁定。当线程1的锁定释放时,线程3锁定删除了值。在这个时候,线程4使用GetOrAdd,并创建新的字典元素(与线程3采用的值不匹配)。我们有2个线程(线程3和线程4)使用相同的密钥。
如果字典中不存在,TryRemove函数已经为您提供了一个默认对象,因此您可以简单地执行以下操作:
static ConcurrentDictionary<int, object> taskDictionary=new ConcurrentDictionary<int, object>();
static void ThreadHandler(int key)
{
try
{
object obj;
// Remove object with key = 'key', or create a new object if it does not yet exist
taskDictionary.TryRemove(key, out obj);
// Do whatever you need to do with 'obj'
// Add the object (back) to the dictionary if necessary
taskDictionary.GetOrAdd(key, obj);
}
finally
{
}
}
以上是关于ConcurrentDictionary和线程的主要内容,如果未能解决你的问题,请参考以下文章
ConcurrentDictionary 与 Dictionary
ConcurrentDictionary线程不安全么,你难道没疑惑,你难道弄懂了么?
ConcurrentDictionary线程不安全么,你难道没疑惑,你难道弄懂了么?
ConcurrentDictionary和Dictionary对比