Windows UI Automation: блокировка потоков при добавлении обработчиков событий
Я пишу программу на C#, которая использует UI Automation через Com Interop. Однако у меня возникла проблема с добавлением / удалением обработчика событий из другого обработчика событий:
Моя программа запускает новый поток MTA и в этом потоке вызывает AddFocusChangedEventHandler().
Я хочу следить за изменениями свойств на сфокусированном элементе. Поэтому в обработчике с измененным фокусом я вызываю RemovePropertyChangedEventHandler() для ранее сфокусированного элемента и AddPropertyChangedEventHandler() для вновь сфокусированного элемента.
Тем не менее, я обнаружил, что после примерно двух изменений фокуса я перестаю получать события с измененным фокусом или с измененным свойством. Я догадываюсь, что что-то блокирует фоновый поток.
Если я удаляю код с измененным свойством, то только отслеживание фокуса работает так, как ожидалось.
Я не уверен, что это актуально - но в документации говорится, что обработчики событий должны быть добавлены / удалены в том же потоке. Поскольку я вызываю AddPropertyChangedEventHandler() в одном событии с измененным фокусом и RemovePropertyChangedEventHandler() в другом событии с измененным фокусом, возможно, что эти два вызова выполняются в разных потоках. Тем не менее, я сомневаюсь, что это так - и даже если бы это было так, оно не должно демонстрировать блокирующее поведение, которое я вижу. Просто упомяну это здесь для полноты.
1 ответ
Здесь может быть несколько проблем. Но стоит отметить, что после удаления RemovePropertyChangedEventHandler вы все равно можете получить еще несколько событий, если в одном элементе несколько событий (например, вы получите несколько измененных структур child_added, если к элементу добавлено несколько дочерних элементов, это может быть похоже с изменением нескольких свойств - но не уверен). Таким образом, если вы получаете несколько событий, ваш код будет вызываться несколько раз, возможно, все испортится.
Другая проблема, как вы указали, заключается в том, что вы не должны подписываться / отказываться от подписки на события из разных тем. Но я думаю, что это уместно, когда есть вероятность того, что эти действия не синхронизированы - если вы подписываетесь и отписываетесь от различных событий (вероятно, в вашем случае), тогда все станет грязно - я рискну сказать, что если вы сделаете sub / unsubs в последовательности с помощью некоторого механизма блокировки, тогда все должно быть хорошо.