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