fma*_*ino 5 c# multithreading visual-studio-2003 timer visual-studio
我已经环顾四周一个多星期了,但找不到其他人遇到与我在这里看到的问题类似的问题。
我正在使用在 Windows XP 上运行并在 Visual Studio 2003 中开发的旧应用程序。大约 3 周前突然之间,应用程序变得没有响应,操作员必须执行 Windows 三指敬礼 (CTRL-ALT- DEL)调出任务管理器,终止应用程序进程(显示为无响应)并重新启动应用程序。
我设法让它在调试器中发生一次,当我暂停应用程序时,它正在等待系统从尝试设置 System.Windows.Forms.Timer.Interval 属性返回。
这是对象以及它似乎挂起的位置,这不是它在源代码中的编写方式
internal static System.Windows.Forms.Timer timerMtimeOut;
// This is in an initialization method.
timerMtimeOut = new System.Windows.Forms.Timer();
timerMtimeOut.Tick += new System.EventHandler(timerMtimeOut_Tick);
// this is how it's value is set.
timerMtimeOut.Interval = 1 * msec; // <-- This is where it was in the debugger
timerMtimeOut.Enabled = true;
private static void timerMtimeOut_Tick(object sender, System.EventArgs e)
{
mTimeOut +=timerMtimeOut.Interval/msec;
}
Run Code Online (Sandbox Code Playgroud)
应用程序基本上变得无响应,必须使用任务管理器关闭并重新启动。
多年来它一直运行良好,然后大约 2-3 周前才开始发生这种情况。
有没有其他人看到过这种行为?
最可能的原因是您以不适合的方式使用计时器。第一行代码给出了提示:
internal static System.Windows.Forms.Timer timerMtimeOut;
Run Code Online (Sandbox Code Playgroud)
没有充分的理由声明System.Windows.Forms.Timer静态,因为这个特定的计时器被设计为链接到特定的窗口(表单实例),并且将导致在该表单的主线程中触发滴答事件。它通过在计时器到达刻度时将消息发送到线程消息队列来实现这一点。然后,该消息与所有其他消息(例如鼠标移动和键盘输入)一起在表单线程 (WndProc) 中进行处理。
如果您实例化多个访问计时器的窗口,那么迟早会出现问题。
当操作系统表示某个进程没有响应时,它会通过查看主线程消息队列中的消息的处理方式来检测这一情况。如果它们没有被处理,那么主线程要么正在运行一个冗长的例程,要么已经进入了一些无限循环。从主线程调用Thread.Sleep()(如您的问题标题中所述)将导致消息处理暂停(并将阻止在睡眠期间处理滴答声)。
冗长的过程应该在单独的线程中运行,以保持应用程序的响应能力。您可能希望显示一个进度条,并为用户提供中止该过程的机会。如果您在主线程中运行冗长的进程,则很难做到这一点。有一个肮脏的解决方法是在循环中的某个位置调用Application.DoEvents(),这将动态处理消息队列。但在使用此解决方法时,您应该非常小心地禁用 UI 按钮,否则您的用户可能会多次(递归地)启动该进程或更改您的进程所依赖的某些其他状态。
有点偏离主题,但变量的名称表明您正在尝试计算一个漫长过程中的间隔数?请注意,如果该冗长的进程在表单的主线程中运行,则计时器的滴答事件将在消息循环中排队,并且仅在该冗长的进程完成其工作并恢复消息处理后才会执行。您在评论中提到的带有 DateTime 字段的方法比使用计时器更简单、更安全、更好。
当您需要一个在刻度被点击时立即执行代码的计时器时,您可以使用System.Threading.Timer而不是System.Windows.Forms.Timer。如果您需要从多个线程控制它,请改用 System.Timers.Timer (该定时器是线程安全的)。请注意,这些计时器将在不同的线程中执行其事件。另请注意,您永远不应该从表单主线程以外的其他线程操作控件或表单。一种简单的方法是使用Control.Invoke()方法内置到框架中,该方法又将使用消息循环对操作进行排队。
| 归档时间: |
|
| 查看次数: |
893 次 |
| 最近记录: |