Изменить заблокированный объект в блоке блокировки - PullRequest
2 голосов
/ 06 августа 2009

У меня возникает конфликт потоков в приложении 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;
            }
        }

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

Ответы [ 3 ]

3 голосов
/ 06 августа 2009

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

private object _pendingTransactionLock = new object();

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

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

См. Выбор Джона Скита, что заблокировать.

0 голосов
/ 06 августа 2009

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

0 голосов
/ 06 августа 2009

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

...