3

我现在负责维护的应用程序严重依赖 Application.DoEvents() 方法,虽然我没有确凿的证据证明所有突然和莫名其妙的应用程序崩溃都是由使用此方法引起的,但到目前为止,大多数我发现的问题似乎在某种程度上与代码执行流程围绕此方法的方式有关。

我在整个代码中看到的模式或多或少如下:

  1. 触发用户触发的事件

  2. 事件处理程序运行

然后:

  1. 产生了一个新线程

  2. 与其阻塞 UI 线程和 UI 直到生成的线程不再运行,或者让控制权离开事件处理程序,代码循环,每次通过调用 Application.DoEvents(),直到它接收到指示生成的线程的信号不再运行。(在某些情况下,派生线程在等待其他事件完成时同时调用 Application.DoEvents()。)

  3. 在允许控制离开事件处理程序之前,在 #2 中看到的模式会重复多次。

或者:

  1. 通过 Show() 或 ShowDialog() 方法创建和显示表单。

  2. 与其阻塞 UI 线程和 UI 的其余部分,直到用户与 Form 交互,或者让控件离开事件处理程序,代码循环,每次通过调用 Application.DoEvents(),直到它接收到一个指示用户已与表单交互。

  3. 下一个 Form 显示给用户,并重复相同的练习,直到许多 Forms 之后的控件最终被允许离开事件处理程序。

我知道当您面前没有代码时很难诊断问题,但是假设对 Application.DoEvents() 的调用在某种程度上与该应用程序的不稳定行为有关,那么最简单的方法是什么无需从头开始重新设计即可修复此应用程序?

是否只是让事件处理程序生成一个新线程,允许控制权立即离开事件处理程序,然后使用 WaitHandle 或其他方式阻止生成的线程而不是重复调用 Application.DoEvents()信号机制,直到生成的线程接收到另一个线程已完成其工作或用户已与表单交互的通知?

4

2 回答 2

1

Besides of good tips with removing DoEvents from threads, have you tried to play with BackgroundWorker class? It's better suited for simple threads operations and communication with forms. http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx http://www.dotnetperls.com/backgroundworker

于 2013-03-29T15:35:31.413 回答
0

您的继承设计存在多个大问题。在不使用核武器的情况下,正如 Hans 所建议的那样(实际上并不是一个坏主意),首先要彻底摆脱来自非 GUI 线程的任何 Application.DoEvents() 调用。

然后开始处理其他堆肥。

于 2013-03-29T14:02:20.913 回答