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

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

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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