Правильный подход к изменению элементов GUI из рабочего потока с помощью Dispatcher?

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

В самом простом случае используется графический интерфейс моего плагина, который что-то делает в рабочем потоке, и когда этот метод завершает свою работу, он вызывает мой обратный вызов. Этот метод обратного вызова обрабатывается из того же потока, поэтому он не может работать с графическим интерфейсом. Однако, когда графический интерфейс моего плагина отображается графическим интерфейсом моего основного приложения, мой графический интерфейс плагина кэширует свою ссылку на Dispatcher — когда мне нужно выполнить обновления графического интерфейса (или, в этом случае, отобразить диалоговое окно), я вызываю Dispatcher.Invoke(.. .).

Есть ли какая-либо опасность в такой настройке Dispatcher в моих плагинах?

Сегодня у меня новая проблема с этим подходом. Мое приложение должно вызывать этот метод в моем плагине, который запускает рабочий поток и отображает диалоговое окно. Если я вызову метод до того, как открою графический интерфейс плагина (который кэширует ссылку Dispatcher), операция завершится ошибкой, поскольку Dispatcher имеет значение null. Я всегда проверяю это, чтобы приложение не вылетало. Однако теперь, когда диалоговое окно не отображается, необходимые взаимодействия с пользователем не могут быть выполнены.

Может ли кто-нибудь предложить лучший метод использования диспетчера, чтобы я мог отображать/изменять элементы графического интерфейса плагина из моего основного приложения? Единственное, о чем я могу думать прямо сейчас, это передать ссылку моего основного приложения на Dispatcher в мой загрузчик плагинов, добавить метод «SetDispatcher» в мой интерфейс плагина, а затем заставить загрузчик плагина вызывать это для каждого плагина, который должен быть загружен.


person Dave    schedule 13.10.2010    source источник


Ответы (2)


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

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

person FMM    schedule 13.10.2010

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

person Dave    schedule 13.10.2010