我正在编写一个C#程序,它通过Com interop使用UI Automation。但是,我在另一个事件处理程序中添加/删除事件处理程序时遇到问题:
我的程序启动一个新的MTA线程,并在该线程上调用AddFocusChangedEventHandler()。
我想监视焦点元素的属性更改。因此,在焦点更改的处理程序中,我在先前聚焦的元素上调用RemovePropertyChangedEventHandler(),并在新聚焦的元素上调用AddPropertyChangedEventHandler()。
但是,我发现在大约两次焦点更改后,我停止获得焦点更改或属性更改事件。我的预感是有些事情阻碍了后台主题。
如果我删除了属性更改的代码,那么焦点跟踪只会按预期工作。
我不确定这是否具有相关性 - 但文档指出应在同一个线程上添加/删除事件处理程序。由于我在一个焦点更改事件中调用AddPropertyChangedEventHandler(),而在另一个焦点更改事件中调用RemovePropertyChangedEventHandler(),因此可能在不同线程上执行这两个调用。但是,我怀疑情况如此 - 即使它是,它也不应该表现出我看到的阻塞行为。只是在这里提到完整性。
答案 0 :(得分:1)
这里可能存在多个问题。但值得注意的是,在RemovePropertyChangedEventHandler之后,如果同一项目上有多个事件,您可能仍会获得更多事件(例如,如果添加了多个子项,则会获得多个child_added结构更改事件一个项目,它可能类似于多个属性更改 - 但不确定)。因此,如果您收到多个事件,您的代码将被多次调用,可能会搞乱。
另一个问题是,正如您所指出的,您不应该订阅/取消订阅来自不同线程的事件。但是,如果有可能这些行为不同步,我认为这是相关的 - 如果您订阅和取消订阅不同的事件(可能在您的情况下),那么事情就会变得混乱 - 我会有危险如果你通过一些锁定机制按顺序执行subs / unsubs那么它应该没问题。