Должен ли я использовать 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