Только что пришла идея, я не видел ее раньше, задаваясь вопросом, думали ли вы, ребята, что это хорошая идея, если она существует, какие-либо распространенные ошибки и т. Д. - а также как ее реализовать.
Несколько раз я обнаруживал, что подписываюсь на событие из потока пользовательского интерфейса, которое будет вызываться из другого потока - например, уведомление о завершении вызова службы.
Моя идея состояла бы в том, чтобысохраните текущий Dispatcher
в блоке add
вместе с делегатом обработчика, затем, когда событие 'запущено', выполните некоторые дополнительные логические операции / проверки, чтобы увидеть, был ли диспетчер, связанный с обработчиком, и Invoke
наэто при необходимости.
Конечно, это будет работать только с потоками с Dispatcher
(или эквивалент Forms - что-то с насосом сообщений, я думаю).Я полагаю, что полезность и чистота зависят от того, должен ли подписчик события беспокоиться о потоке, вызываемом обработчиком, или нет?
Редактировать: Похоже, это не так уж плохо - кроме того, кто-нибудьесть идеи как реализовать?Используя Delegate.Combine
, как, например, вы могли бы вызывать каждый обработчик для другого Dispatcher
?Вместо этого вы бы хранили делегаты в составном объекте в List
и вызывали их по очереди в методе On(Whatever)
, или есть что-то более приятное?
... Глядя на источник BackgroundWorker
вОтражатель, вызывать нечего:
protected virtual void OnProgressChanged(ProgressChangedEventArgs e)
{
ProgressChangedEventHandler handler = (ProgressChangedEventHandler) base.Events[progressChangedKey];
if (handler != null)
{
handler(this, e);
}
}
Если я что-то упустил?
Итак, BackgroundWorker
делает это с AsyncOperation
.Как насчет общего решения, только для обработчиков событий, в средствах доступа к событиям?BackgroundWorker
может сойти с рук, как он работает, потому что метод вызывается из клиента - в более общем случае, единственный раз, когда вы будете иметь доступ к потоку обработчика, находится в методе доступа к событию?:)