我有一个从第三方库引发的事件,它在后台线程上执行。此事件基本上通知侦听器库正在监视的系统中的状态更新。如果InvokeRequired为true,则处理程序在UI线程上调用自身,并且在任何一种情况下,然后继续将状态更改的条目附加到文本框中的文本,并在托盘中弹出通知。
现在,问题是这些状态更新可以非常迅速地进行;被监视的系统可以在几毫秒内从“空闲”状态通过几个中间体进入“就绪”状态。我需要知道系统已经过渡到所有这些中间状态;但是,并非所有状态更改都会进入日志。设置断点并单步执行处理程序会显示最奇怪的行为;处理程序将逐步执行前几行代码,然后跳转回方法的条目。这几乎就像事件或Windows消息泵正在中止方法调用一样,因为对同一方法的另一次调用是传入的。将方法体放在锁定块中并不能解决问题。
我之前在其他不使用此第三方库的项目中看到了这一点。我并不那么担心,因为快速事件只是触发窗口重绘。如果他们都发生了,那很好,但是如果一个人被短路了,管道中还会有另一个人通过。然而,这是一个更具应用关键性的任务,必须在事件每次引发时按顺序发生(它不必像状态实际发生的那样快地发生;绝对不会期望这样)。
这种短路行为的原因是什么,如何阻止它?
答案 0 :(得分:1)
您所看到的内容很可能是在您第一次开始单步调用时仍在运行的后台线程中对事件处理程序的新调用。
答案 1 :(得分:0)
而不是在线程中同步执行所有工作,而事件处理程序在其中触发可能有利于在另一个线程中完成工作。
只需将您在当前事件处理程序中执行的所有内容包装在Task.Factory.StartNew
中,或使用BeginInvoke
封送到UI线程而不是Invoke
。
我无法确定,因为我不知道该库,但可能是它在完成执行上一个事件的所有事件处理程序之前无法触发更多事件。
您可能需要做的另一个选择,无论是为了解决这个问题,还是为了防止您的UI因为这么多的更新而生气,就是将状态更改作为进入并将它们转储到集合中,然后只是定期检查该集合并处理批量中的所有更改。这对于第三方对象的事件处理程序来说会更容易,因为它只需要将一个项目添加到集合中,并且在UI上也更容易,因为它不需要在监视器甚至可以在时间跨度内多次更新渲染变化。