Должен ли я использовать Invoke или SynchronizationContext для обновления элементов управления формы из другого потока? - PullRequest
4 голосов
/ 20 сентября 2011

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

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

Что предпочтительнее?

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

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

Редактировать: Также теперь я вижу, что есть TaskScheduler.FromCurrentSynchronizationContextмаршрут также .. Так много вариантов x_x

Ответы [ 2 ]

6 голосов
/ 20 сентября 2011

Я предпочитаю SynchronizationContext, чем Control.Invoke. Опасность Control.Invoke в том, что существует пожизненная проблема с владельцем Control. Если элемент управления расположен, когда вы пытаетесь набрать на нем Invoke, это ставит под угрозу способность вызова к успеху. Это происходит, когда диалоги закрыты, смещены представления и т. Д ...

SynchronizationContext.Current хотя обычно живет столько же, сколько и нить, с которой он связан. Он имеет конечное время жизни и, следовательно, в конечном итоге те же проблемы, но он немного более предсказуем, чем Control.

0 голосов
/ 20 сентября 2011

Вы рассматривали возможность использования компонента Background Worker?Для долгосрочных задач, которые не должны связывать пользовательский интерфейс, это простой и понятный способ получить многопоточные возможности.Например, вы можете выполнить обновления пользовательского интерфейса, используя событие ProgressChanged, а фоновый работник и класс фонового рабочего обеспечат, чтобы поток, создавший BW, выполнял события ProcessChanged и WorkComplete.Так что, если вы сделали BW из пользовательского интерфейса и включили его в работу, вы можете безопасно обновить его там.

Вот небольшая статья от MS http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx

Еще одна действительно хорошая ссылкаhttp://www.albahari.com/threading/part3.aspx#_BackgroundWorker

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...