kzen.dev
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
 Larsenal
Larsenal
Вопрос

Почему в WinForms вы не можете обновлять элементы управления пользовательского интерфейса из других потоков?

Я уверен, что для этого есть веская (или, по крайней мере, достойная) причина. Что это?

18 2008-08-13T20:41:24+00:00 7
Программирование
winforms
multithreading
Brian Ensink
Brian Ensink
13-го августа 2008 в 10:34
2008-08-13T22:34:57+00:00
Дополнительно
Источник
Редактировать
#8414338

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

Конечно, единственная причина - это там что-то в структуре где-нибудь это isn' t очень безопасный от нити.

Это " something" почти каждый участник случая на каждом контроле в Системе. Windows. Формы.

Документация MSDN для многих средств управления в Системе. Windows. Формы, если не все они, говорят " Любая статичная общественность (Разделенный в Visual Basic) члены этого типа является безопасной нитью. Любые участники случая, как гарантируют, не будут безопасной &quot нитью;

Это означает что участники случая, такие как 'TextBox. Текст {добирается; набор;}' не reentrant .

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

[Отредактировать]

Хотя этот вопрос только спрашивает " why" вот связь со статьей, которая объясняет " how":

Как к: сделайте безопасные от нити звонки Windows Forms Controls на MSDN

http://msdn.microsoft.com/en-us/library/ms171728.aspx

Brian Ensink
Brian Ensink
Редактировал ответ 13-го августа 2008 в 11:03
25
0
Решение / Ответ
John Sibly
John Sibly
13-го августа 2008 в 8:47
2008-08-13T20:47:12+00:00
Дополнительно
Источник
Редактировать
#8414335

Потому что вы можете легко зайти в тупик (среди прочих проблем).

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

В других языках, таких как C++, вы можете попытаться сделать это (без исключения, как в WinForms), но ваше приложение может зависнуть и перестать отвечать, если возникнет тупик.

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

myControl.BeginInvoke(myControl.UpdateFunction);

Это эквивалентно выполнению C++/MFC PostMessage из рабочего потока

John Sibly
John Sibly
Редактировал ответ 17-го апреля 2015 в 3:43
9
0
Björn Waide
Björn Waide
13-го августа 2008 в 11:09
2008-08-13T23:09:03+00:00
Дополнительно
Источник
Редактировать
#8414339

Хотя это кажется разумным ответом Джонса isn' t правильный. На самом деле, даже когда использование Призывает you' ре, все еще безопасное не столкновение с ситуациями тупика. Когда контакт с событиями стрелял в фоновое использование нити, Призывают, мог бы даже привести к этой проблеме.

< br/>

Настоящая причина больше имеет отношение к условиям гонки и отводит назад в древние времена Win32. Я can' t объясняют детали здесь, ключевые слова - насосы сообщения, события WM_PAINT и тонкие различия между " SEND" и " POST".

< br/>

Дополнительная информация может быть найдена здесь здесь и здесь.

7
0
 Quibblesome
Quibblesome
13-го августа 2008 в 8:52
2008-08-13T20:52:21+00:00
Дополнительно
Источник
Редактировать
#8414336

В версиях 1.0/1.1 исключения при отладке не возникало, вместо этого возникал периодический сценарий зависания во время выполнения. Класс! :) Поэтому в версии 2.0 они сделали так, чтобы этот сценарий выбрасывал исключение, и совершенно справедливо.

Фактическая причина этого, вероятно (как утверждает Адам Хейл), заключается в каком-то параллелизме/проблеме блокировки. Обратите внимание, что обычный .NET api (например, TextBox.Text = "Hello";) оборачивает команды SEND (которые требуют немедленного действия), что может создать проблемы, если они выполняются в отдельном потоке от того, который выполняет обновление. Использование Invoke/BeginInvoke вместо этого использует POST, который ставит действие в очередь.

Более подробная информация о SEND и POST здесь.

2
0
Andrew Grant
Andrew Grant
13-го августа 2008 в 9:26
2008-08-13T21:26:44+00:00
Дополнительно
Источник
Редактировать
#8414337

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

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

1
0
Adam Haile
Adam Haile
13-го августа 2008 в 8:44
2008-08-13T20:44:01+00:00
Дополнительно
Источник
Редактировать
#8414334

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

Редактировать:

В других языках, таких как C++ вы свободно можете попытаться сделать это (без исключения, как в WinForms), но вы > в конечном счете, научитесь нелегкому пути!

Ах да... Я переключаюсь между C/C++ и C# и поэтому был немного более общим, чем должен был, извините... Он прав, вы можете сделать это в C/C++, но это вернется, чтобы укусить вас!

Adam Haile
Adam Haile
Редактировал ответ 13-го августа 2008 в 8:50
1
0
Chris Hughes
Chris Hughes
13-го октября 2008 в 1:44
2008-10-13T13:44:54+00:00
Дополнительно
Источник
Редактировать
#8414340

Хм I' m не вполне уверенный, но я думаю, что, когда у нас есть прогресс средства управления как бары ожидания, индикаторы выполнения, мы можем обновить их ценности от другой нити, и все работает отлично без любых затруднений.

-1
0
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Денис Васьков
Зарегистрирован 16 часов назад
2
Dima Patrushev
Зарегистрирован 2 дня назад
3
sirojidddin otaboyev
Зарегистрирован 1 неделю назад
4
Елена Гайдамамакинат
Зарегистрирован 1 неделю назад
5
Иван Степанюк
Зарегистрирован 1 неделю назад
ID
KO
RU
© kzen.dev 2023
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией