Windows UI自动化:添加事件处理程序时线程阻塞

本文关键字:线程 程序 事件处理 UI 自动化 添加 Windows | 更新日期: 2023-09-27 18:01:58

我正在编写一个c#程序,它通过Com互操作使用UI自动化。然而,我有一个问题,从另一个事件处理程序中添加/删除事件处理程序:

我的程序启动了一个新的MTA线程,并在该线程上调用AddFocusChangedEventHandler()。

我想监视焦点元素上的属性更改。因此,在焦点更改处理程序中,我对先前聚焦的元素调用RemovePropertyChangedEventHandler(),对新聚焦的元素调用AddPropertyChangedEventHandler()。

然而,我发现在大约两次焦点更改之后,我不再获得焦点更改或属性更改的事件。我的预感是有什么东西阻塞了后台线程。

如果我删除了属性更改的代码,那么焦点跟踪就会像预期的那样工作。

我不确定这是否是百分之百-但是文档指出事件处理程序应该在同一线程上添加/删除。由于我在一个焦点更改事件中调用AddPropertyChangedEventHandler(),在另一个焦点更改事件中调用RemovePropertyChangedEventHandler(),因此这两个调用可能在不同的线程上执行。然而,我对此表示怀疑——即使是这样,它也不应该表现出我所看到的阻塞行为。为了完整起见,这里只提一下。

Windows UI自动化:添加事件处理程序时线程阻塞

这里可能有多个问题。但是值得注意的是,在你RemovePropertyChangedEventHandler之后,如果在同一个项目上有多个事件,你可能仍然会得到一些更多的事件(例如,如果有多个孩子被添加到一个项目上,你会得到多个child_added结构改变的事件,它可能与多个属性改变类似-但不确定)。所以,如果你得到多个事件,你的代码将被调用多次,可能会把事情搞砸。

另一个问题是,正如你所指出的,你不应该订阅/取消订阅来自不同线程的事件。但我认为这是相关的,当有一个机会,这些行动是不同步的-如果你订阅和取消订阅不同的事件(可能在你的情况下),然后事情会变得混乱-我冒昧地说,如果你做订阅/取消订阅顺序通过一些锁机制,那么它应该是好的。