У меня есть класс Worker и класс MainForm/UI. Из класса пользовательского интерфейса я создаю новый экземпляр класса Worker в новом фоновом потоке. Этот поток добавляет несколько обновлений к элементам управления пользовательского интерфейса. Поскольку они находятся в разных классах, я в основном передаю экземпляр MainForm (это) и соответствующий делегат для обновления элементов управления в конструктор рабочего класса. В конструкторе я устанавливаю mainForm на объект ISynchronizeInvoke
(назовите его _synch), а затем, далее в рабочем классе, сделайте _synch.Invoke(theDelegate, new object[] { "new value" })
.ISynchronizeInvoke vs SynchronizationContext vs mainForm.Invoke
Это все работает нормально, но потом я понял, что также можно сделать просто mainForm.Invoke
(не используя объект ISynchronizeInvoke
). Какая разница между двумя?
Чтобы усугубить ситуацию, я прочитал в статье, что ISynchronizeInvoke
больше не нужен, теперь, когда SynchronizationContext
пришел долго. Я понимаю, что я не понимаю, для чего эти два. Любая помощь с пониманием, почему я должен использовать Invoke для этих объектов, а не непосредственно на mainForm, будет с благодарностью оценена.
ISynchronizeInvoke полезна только в другую библиотеку, которая делает * не * есть идея, какая именно нить нить UI или как правильно ссылаться на код, который манипулирует интерфейс. Никогда не проблема с классом Form, это * это * пользовательский интерфейс. И реализует водопровод, который заставляет работать ISynchronizeInvoke.К сожалению, WPF нарушил контракт, поэтому он больше не является интерфейсом общего назначения. –
@ HansPassant Спасибо Хансу. Я попытался переключиться на 'SynchronizationContext', как было предложено Sriram, но Send и Post не принимают пользовательские делегаты. Они принимают делегат SendOrPostCallback, который имеет только один параметр ('object'). У моего текущего пользовательского делегата есть как строка значений (текст, который я хочу взять ярлык), так и строка lbName, так что метод может определить, какой элемент управления меткой обновляется. Что вы мне посоветовали? Должен ли я просто придерживаться Form.Invoke? Благодаря! – Anders
Использование Invoke ошибочно в 99% случаев. Очень подвержен тупиковой ситуации и расам, всегда используйте BeginInvoke. Единственного объекта достаточно для хранения * ничего *, при необходимости используйте небольшие вспомогательные классы. Лямбда - почти всегда удобная альтернатива. –