Подтвердить что ты не робот

Ключевое слово блокировки в С#

Я понимаю основную функцию ключевого слова блокировки из MSDN

Заявление о блокировке (ссылка на С#)

Ключевое слово блокировки обозначает оператор блокировать как критический получение блокировки взаимного исключения для данного объекта, выполняющего и затем освободить блокировка.

Когда следует использовать замок?

Например, это имеет смысл в многопоточных приложениях, поскольку защищает данные. Но нужно ли, когда приложение не выделяет другие потоки?

Есть ли проблемы с производительностью при использовании блокировки?

Я только что унаследовал приложение, которое использует блокировку повсюду, и оно однопоточное, и я хочу знать, должен ли я их оставить, они даже необходимы?

Обратите внимание, что это скорее общий вопрос о знаниях, скорость приложения - это хорошо, я хочу знать, является ли это хорошим шаблоном проектирования, который следует соблюдать в будущем, или этого следует избегать, если это абсолютно необходимо.

4b9b3361

Ответ 1

Когда следует использовать блокировку?

Блокировка должна использоваться для защиты общих ресурсов в многопоточном коде. Ни для чего другого.

Но нужно ли, когда приложение не выделяет какие-либо другие потоки?

Абсолютно нет. Это просто время. Однако не забудьте, что вы неявно используете системные потоки. Например, если вы используете асинхронный ввод-вывод, вы можете получать обратные вызовы из случайного потока, а не из исходного потока.

Есть ли проблемы с производительностью при использовании блокировки?

Да. Они не очень большие в однопоточном приложении, но зачем делать звонки вам не нужны?

... если это хороший шаблон дизайна, который следует в будущем [?]

Блокировка всех волей-неволей - страшный шаблон дизайна. Если ваш код загроможден случайным блокированием, а затем вы решите использовать фоновый поток для некоторой работы, вы, вероятно, столкнетесь с взаимоблокировками. Совместное использование ресурса между несколькими потоками требует тщательной разработки, и чем больше вы можете изолировать сложную часть, тем лучше.

Ответ 2

Все ответы здесь кажутся правильными: полезность замков заключается в том, чтобы блокировать потоки от одновременного блокирования кода. Однако в этом поле есть много тонкостей, один из которых состоит в том, что блокированные блоки кода автоматически помечены как критические области по времени выполнения Common Language.

Эффект от маркировки кода как критического заключается в том, что если весь регион не может быть полностью выполнен, среда выполнения может считать, что весь ваш домен приложения потенциально подвержен опасности и, следовательно, выгружает его из памяти. Чтобы процитировать MSDN:

Например, рассмотрите задачу, которая пытается выделить память, удерживая блокировку. Если выделение памяти не выполняется, прерывание текущей задачи недостаточно для обеспечения стабильности AppDomain, поскольку в домене могут быть другие задачи, ожидающие такой же блокировки. Если текущая задача завершена, другие задачи могут быть заблокированы.

Поэтому, несмотря на то, что ваше приложение однопоточное, это может быть опасно для вас. Учтите, что один метод в заблокированном блоке генерирует исключение, которое в конечном итоге не обрабатывается внутри блока. Даже если исключение обрабатывается по мере того, как оно пузырится через стек вызовов, ваша критическая область кода не заканчивается нормально. И кто знает, как CLR будет реагировать?

Для получения дополнительной информации прочитайте эту статью о опасностях Thread.Abort( ).

Ответ 3

Помните, что могут быть причины, по которым ваше приложение не однопоточно, как вы думаете. Асинхронный ввод-вывод в .NET может также вызвать обратный вызов в потоке пула, например, как и некоторые из различных классов таймера (но не Таймер Windows Forms).

Ответ 4

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

Ответ 5

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

Блокировка на самом деле является сериализатором доступа к памяти, потоки (которые принимают блокировку) будут ждать, пока блокировка будет введена до тех пор, пока текущий поток не выйдет из блокировки, поэтому доступ к памяти будет сериализован.

Чтобы ответить на вопрос, блокировка вопроса не требуется в однопоточном приложении и имеет побочные эффекты производительности. потому что блокировки на С# основаны на объектах синхронизации ядра, и каждая блокировка, которую вы берете, создает переход в режим ядра из пользовательского режима.

Если вам интересна производительность многопоточности, то хорошее место для начала - Рекомендации по потокам MSDN

Ответ 6

У вас могут быть проблемы с производительностью с фиксированными переменными, но обычно вы создаете свой код, чтобы свести к минимуму длительность времени, затрачиваемую на блокировку кода.

Что касается удаления блокировок. Это будет зависеть от того, что именно делает код. Несмотря на то, что однопоточное, если ваш объект реализован как Singleton, возможно, что вы будете иметь несколько клиентов, используя его экземпляр (в памяти, на сервере) в то же время..

Ответ 7

Да, при использовании блокировки будет наблюдаться некоторая производительность, но она вообще небрежна, чтобы не иметь значения.

Использование блокировок (или любого другого оператора взаимного исключения или конструкции) обычно требуется только в многопоточных сценариях, где несколько потоков (или ваших собственных решений или от вашего вызывающего) имеют возможность взаимодействовать с объектом и изменять базовое состояние или данные. Например, если у вас есть коллекция, к которой можно получить доступ несколькими потоками, вы не хотите, чтобы один поток менял содержимое этой коллекции, удаляя элемент, пока другой поток пытается его прочитать.

Ответ 8

Блокировка (токен) используется только для отметки одного или нескольких блоков кода, которые не должны запускаться одновременно в нескольких потоках. Если ваше приложение однопоточное, оно защищает от состояния, которое не может существовать.

И блокировка вызывает обращение к производительности, добавляя инструкции для проверки на одновременный доступ до выполнения кода. Его следует использовать только там, где это необходимо.

Ответ 9

См. question об 'Mutex' в С#. И затем рассмотрите эти два вопроса относительно использования оператора "lock (Object)".

Ответ 10

Нет смысла устанавливать блокировки в приложении, если есть только один поток, и да, это поражает производительность, хотя для этого удара требуется довольно много вызовов, чтобы вложить что-то значительное.