ConcurrentDictionary和线程

问题描述 投票:-1回答:1

我在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)使用相同的密钥。

c# multithreading thread-safety concurrentdictionary
1个回答
0
投票

如果字典中不存在,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
    {
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.