我对 Windows 窗体事件有一个奇怪的问题。确切地说,这是一个KryptonHeaderGroup的 ButtonSpec Click 事件,但它也发生在普通 vanillaSystem.Windows.Forms.Button
中。
在单击事件中,用户界面被关闭(左侧有一个标签和一个取消按钮),然后从先前的用户输入构建一个昂贵的 LINQ 查询,编译然后执行。foreach 中有Application.DoEvents()
实际执行查询的调用(它是对象的 LINQ,所以它很懒惰)。这使用户能够按下取消,并且在 之后DoEvents
,测试取消标志并取消 foreach,并进行一些清理。到现在为止还挺好。
但是,当我在前几个结果出现后按下取消按钮时(标签显示已经有多少),整个 Click 事件处理程序重新启动!添加一些跟踪后,这似乎发生在前一个处理程序返回之前。换句话说,它发生在其中一个DoEvents
调用中。当然,该按钮不再被按下。如果按钮在事件处理程序中被禁用,则不会发生这种情况。但是由于没有按下按钮,它不应该再次触发它的 Click 事件,不是吗?
我很困惑。显然,解决方法是禁用该按钮,但我想知道这里的实际问题可能是什么。DoEvents
如果在处理程序完成之前调用事件处理程序,是否可以重新启动?DoEvents
在事件处理程序中不推荐/不允许调用吗?但是,由于一切都是事件驱动应用程序中的事件处理程序,你永远不能调用它:)
回答此问题可能需要的其他提示:
- LINQ 查询最初需要很长时间才能提供第一个结果,即在进行第一次
DoEvents
调用之前。 - LINQ 查询在 GUI 线程中运行,因为允许用户访问其余应用程序没有意义,因为访问会干扰 GUI 和 LINQ 查询使用的底层 API。
- 我知道我应该将 LINQ 查询加载到一个单独的应用程序域并在那里执行它,以便能够卸载它。但是典型用户只会运行几个不同的查询,并且生成的程序集被缓存(对于相同的查询字符串)。
- 如果我启用了断点( sigh - Heisenberg,有人吗?)或者我稍后在查询期间取消,则问题不再发生。
我很感激任何可以解释这种行为的东西,即使这只是猜测:)