У меня есть служба WCF в пуле приложений IIS. Метод службы 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), которые работают с одним и тем же ключом.