Почему только пользовательский интерфейс разрешает изменять пользовательский интерфейс?

Я знаю, что если я изменяю элемент управления из другого streamа, я должен позаботиться, потому что WinForms и WPF не позволяют изменять состояние управления из других streamов.

Почему это ограничение на месте?

Если я могу написать streamобезопасный код, я должен иметь возможность изменять состояние управления безопасно. Тогда почему это ограничение присутствует?

Это ограничение ограничено несколькими графическими интерфейсами. Согласно книге Java Concurrency на практике причина этого заключается в том, чтобы избежать сложной блокировки. Проблема в том, что элементы управления графическим интерфейсом, возможно, придется реагировать на оба события из пользовательского интерфейса, привязки данных и т. Д., Что приводит к блокировке из нескольких разных источников и, следовательно, к риску взаимоблокировок. Чтобы избежать этого, .NET WinForms (и другие пользовательские интерфейсы) ограничивает доступ к компонентам в один stream и, таким образом, позволяет избежать блокировки.

В случае окон, когда создается элемент управления, обновления пользовательского интерфейса выполняются через сообщения от насоса сообщений. Программист не имеет прямого управления streamом, на котором работает насос, поэтому приход сообщения для управления может привести к изменению состояния элемента управления. Если другому streamу (который программист был в непосредственном подчинении) было позволено изменить состояние элемента управления, тогда потребуется некоторая логика синхронизации, чтобы предотвратить повреждение состояния управления. Элементы управления в .Net не являются streamобезопасными; это, я подозреваю, по дизайну. Помещение логики синхронизации во всех элементах управления было бы дорогостоящим с точки зрения проектирования, разработки, тестирования и поддержки кода, который обеспечивает эту функцию. Программист мог бы, конечно, обеспечить безопасность streamа для управления своим собственным кодом , но не для кода, который находится в .Net, который работает одновременно с его кодом. Одним из решений этой проблемы является ограничение этих типов действий только на один stream и только один stream, что упрощает управление управляющим кодом в .NET.

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

Возможно, вы сможете сделать свой собственный код streamобезопасным, но вам не нужно вводить необходимые примитивы синхронизации во встроенный код WinForm и WPF, соответствующий вашим кодам. Помните, что за кулисами происходит много сообщений, которые в конечном итоге заставляют stream пользовательского интерфейса получать доступ к элементу управления, даже если вы его вообще не понимаете.

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

На самом деле, насколько я знаю, это был план с самого начала! Доступ к любому элементу управления можно получить из любого streamа! И только потому, что блокировка streamов была необходима, когда другой stream требовал доступа к элементу управления – и потому, что блокировка дорогая – была создана новая модель streamовой обработки, называемая «аренда streamов». В этой модели связанные элементы управления будут объединены в «контексты», используя только один stream, тем самым уменьшая необходимое количество блокировки. Довольно круто, да?

К сожалению, эта попытка была слишком смелой, чтобы преуспеть (и немного сложнее, потому что блокировка по-прежнему требуется), поэтому хорошая старая модель streamовой обработки Windows Forms – с единственным streamом пользовательского интерфейса и с создающим streamом, требующим права собственности на элемент управления – снова используется в wPF, чтобы сделать нашу жизнь … проще?

Windows поддерживает множество операций, которые, в частности, используются в комбинации, по своей сути не являются streamобезопасными. Например, если один stream пытается вставить какой-либо текст в текстовое поле, начинающееся с 50-го символа, а другой stream пытается удалить первые 40 символов из этого поля? Было бы возможно, чтобы Windows использовала блокировки, чтобы гарантировать, что вторая операция не может быть начата до тех пор, пока первая не будет завершена, но использование блокировок добавит накладные расходы для каждой операции, а также повысит вероятность взаимоблокировки, если действия на одном объекте потребуют манипуляции с другим. Требование о том, что действия, связанные с конкретным окном, должны происходить в конкретном streamе, является более жестким требованием, чем это необходимо для предотвращения одновременного выполнения небезопасных комбинаций операций, но его относительно легко анализировать. Использование элементов управления из нескольких streamов и предотrotation столкновений с помощью некоторых других средств обычно будет более сложным.

  • Как Thread может вернуть значение после завершения работы?
  • Недопустимая проблема с доступом к нескольким streamам
  • Создавать streamи в java для работы в фоновом режиме
  • Почему не логично синхронизировать логику?
  • Как убить stream мгновенно в C #?
  • Простой пример streamовой обработки в C ++
  • STL-вектор и безопасность streamов
  • Являются ли Thread.stop и друзьями безопасными в Java?
  • Можно ли заставить существующее приложение Java использовать не более x ядер?
  • Что такое блокировка уровня classа в java
  • Многопоточность в VBA
  • Давайте будем гением компьютера.