Изменить заблокированный объект в блоке блокировки

2

У меня возникли проблемы с потоком в приложении OLTP. При просмотре кода, я нашел следующее:

        lock (_pendingTransactions)
        {
            transaction.EndPointRequest.Request.Key = (string)MessageComparer.GenerateKey(transaction.EndPointRequest.Request);

            if (!_pendingTransactions.ContainsKey(transaction.EndPointRequest.Request.Key))
            {
                _pendingTransactions.Add(transaction.EndPointRequest.Request.Key, transaction);

                return true;
            }
            else
            {
                return false;
            }
        }

Как вы можете видеть в фрагменте, существует блокировка объекта, который изменяется в блоке блокировки. Что-то плохое с этим? У кого-нибудь были проблемы с этим?

Теги:
thread-safety
synchronization

3 ответа

3
Лучший ответ

Использование блокировки таким образом часто обескураживается, при этом рекомендуется использовать выделенное поле блокировки (переменная члена класса). Специальное поле блокировки имеет тип Object и обычно выглядит так:

private object _pendingTransactionLock = new object();

Если сам объект имеет некоторое представление о потоках, эта переменная блокировки может принадлежать классу _pendingTransaction. В противном случае он может принадлежать _pendingTransaction в поле, объявляющем класс.

Вы не говорите, какой тип _pendingTransaction. Если это встроенный класс коллекции, который предоставляет свойство SyncRoot, это может быть хорошим выбором для блокировки.

См. Jon Skeet Выбор того, что блокировать.

0

Вообще говоря, один будет блокировать объект, потому что он собирается его модифицировать (или читать), поэтому в этом нет ничего неправильного.

0

Вероятно, генерация ключа может быть выведена за пределы блокирующего блока, чтобы уменьшить продолжительность блокировки. Кроме этого, это почти канонический пример блокировки, который защищает список/коллекцию/массив: получить блокировку, проверить, существует ли ключ, добавить ключ, если он еще не существует, отпустить блокировку.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню