禁用Windows窗体上的所有事件

时间:2010-10-01 16:13:25

标签: .net winforms multithreading events

有没有办法暂时禁用Windows窗体上的所有事件?

我遇到辅助线程上的处理被主线程上的事件破坏的情况。 (主线程事件正在修改数据绑定到辅助线程使用的变量的控件的内容。)寻找一种“锁定”表单的方法,直到辅助线程上的处理完成。 (显然,将处理转移到主线程会这样做 - 但它也会“冻结”UI,这也不是我想要的。)

5 个答案:

答案 0 :(得分:2)

一些不同的选项可以让您解决这个问题:

  • 禁用任何会触发非线程安全事件的控件
  • 使用同一个对象上的监视器锁定修改变量或所有事件提升者的所有代码,或
  • 分离并重新连接所有处理程序。

我会选择第一个选项,可能还有将光标设置为沙漏和/或在状态栏中设置消息。它很简单,有效,并且不会导致实际UI冻结。我会避免第三种选择,因为它会“破坏”表单在其工作时的行为。第二种选择的功效取决于你如何实施它;它可以很容易地冻结UI,这是你不想做的事情。

答案 1 :(得分:2)

这是一个标准的线程问题。即使你可以阻止事件,很难做到,它仍然无法解决问题。因为当你想要开始阻止时,事件处理程序可能已经启动但尚未完成。

它有一个标准的解决方案,使用lock关键字。

如果这不可行,因为用户需要在再次运行查询之前更改多个控件,那么您需要先终止正在运行的线程。例如,BackgroundWorker.CancelAsync。如果这不可行,因为取消查询需要很长时间,那么您需要在查询运行时将控件Enabled属性设置为false。

答案 2 :(得分:1)

阻止表单上的事件有效地冻结了UI。事件作为消息泵中标准消息处理的一部分发生 - 停止事件将冻结UI。

最好在处理工作时禁用UI功能(例如禁用单个按钮等),然后在完成时重新启用它们。这将允许发生正常事件,但阻止用户触发按钮单击等

答案 3 :(得分:1)

如果您要取消PostMessage产生的所有事件,则可以实施IMessageFilter界面并使用AddMessageFilter

这可能会捕获您感兴趣的所有事件。它不会捕获所有内容,例如SendMessage导致的事件。要绝对捕获所有内容,您需要thread-specific application hook

请注意,这会导致UI完全冻结,这可能不是您想要的。更好的应用可能是拦截适当的事件并在后台工作正在进行时抑制不需要的行为。

答案 4 :(得分:1)

感谢所有人的出色帮助。真的帮助了决策过程。向大家致敬。结束使用锁。 (即每个事件处理程序开始时的if语句在继续之前检查锁定状态。)乏味而不是所有那些“酷”技术上,但简单而且有效。