Потокобезопасен в том смысле, что внутреннее состояние ConcurrentDictionary
не будет повреждено. Это основная гарантия, предлагаемая этим классом. Так что если вы вызываете foo[bar] = fiz
из одного потока и foo[bar] = biz
из другого потока одновременно, то либо fiz
, либо biz
будет окончательно сохранено как значение ключа bar
, при условии, что этот ключ уже существовал вcollection (иначе исключение будет выдано обоими потоками).
Это как если бы foo[bar]
была переменной с размером собственного целого числа или меньше, например short count;
. Безопасно обновить эту переменную из нескольких потоков, в том смысле, что ее внутренние биты не будут частично обновлены и всегда будут содержать последнее назначенное значение. Если этой гарантии недостаточно для вашей программы, например, если вы хотите, чтобы count
содержал что-то значимое, например, сколько раз было обновлено, вам придется синхронизировать доступ к этой переменной.
В случае ConcurrentDictionary
, если вы хотите, чтобы foo[bar]
содержал значение biz
, только если это было ранее fiz
, тогда это , а не поточно-ориентированный: if (foo[bar] == fiz) foo[bar] = biz
. Вам придется использовать метод TryUpdate
: foo.TryUpdate(bar, biz, fiz)
. Другой случай: если вы хотите, чтобы foo[bar]
содержал значение biz
, только если оно было , а не ранее fiz
, тогда вам не повезло. ConcurrentDictionary
не включает метод, который предлагает эту гарантию. Таким образом, вы будете вынуждены вернуться назад, используя Dictionary
+ ручную синхронизацию.