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

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

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

Что является предпочтительным?

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

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

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

2 ответа

Решение

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

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

Вы изучали использование компонента 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

Другие вопросы по тегам