1

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

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

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

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

如果我删除属性更改的代码,那么焦点跟踪将按预期工作。

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

4

1 回答 1

1

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

另一个问题是,正如您所指出的,您不应该订阅/取消订阅来自不同线程的事件。但是我认为当这些操作有可能不同步时,这是相关的——如果你订阅和取消订阅不同的事件(可能是你的情况),那么事情就会变得一团糟——我会冒昧地说,如果你这样做通过某种锁定机制按顺序订阅/取消订阅,那么它应该没问题。

于 2016-06-15T05:44:01.660 回答