Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 线程。睡眠还是线程。计时器挂起系统?_C#_Multithreading_Visual Studio_Timer_Visual Studio 2003 - Fatal编程技术网

C# 线程。睡眠还是线程。计时器挂起系统?

C# 线程。睡眠还是线程。计时器挂起系统?,c#,multithreading,visual-studio,timer,visual-studio-2003,C#,Multithreading,Visual Studio,Timer,Visual Studio 2003,我已经到处找了一个多星期了,我没有找到任何人有类似的问题,我在这里看到的 我正在使用一个运行在WindowsXP上的旧应用程序,它是在VisualStudio2003中开发的。大约3周前,应用程序突然变得无响应,操作员必须执行Windows三指敬礼(CTRL-ALT-DEL)来启动任务管理器,终止应用程序进程(显示为无响应)并重新启动应用程序 我设法在调试器中让它发生一次,当我暂停应用程序时,它正在等待系统从尝试设置system.Windows.Forms.Timer.Interval属性返回

我已经到处找了一个多星期了,我没有找到任何人有类似的问题,我在这里看到的

我正在使用一个运行在WindowsXP上的旧应用程序,它是在VisualStudio2003中开发的。大约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;
}
内部静态系统.Windows.Forms.Timer Timer超时;
//这是一个初始化方法。
timerMtimeOut=new System.Windows.Forms.Timer();
timerMtimeOut.Tick+=新系统.EventHandler(timerMtimeOut\u Tick);
//这就是它的值的设置方式。

timerMtimeOut.Interval=1*msec;// 最有可能的原因是您使用计时器的方式不是为其构建的。第一行代码给出了一个提示:

internal static System.Windows.Forms.Timer timerMtimeOut;
没有充分的理由声明
System.Windows.Forms.Timer
static,因为此特定计时器被设计为链接到特定窗口(表单实例),并将导致在该表单的主线程中触发勾号事件。它通过在计时器点击滴答声时将消息发送到线程消息队列来实现。然后在表单线程(WndProc)中处理该消息以及所有其他消息,如鼠标移动和键盘输入

如果实例化多个访问计时器的窗口,那么问题迟早会出现

当操作系统说某个进程没有响应时,它会通过查看主线程消息队列中的消息是如何处理的来检测这一点。如果它们没有被处理,那么要么主线程正在运行一个冗长的例程,要么进入了某个无限循环。从主线程调用
Thread.Sleep()
(如问题标题中所述)将导致消息处理暂停(并将阻止在睡眠期间处理记号)

冗长的过程应该在单独的线程中运行,以保持应用程序的响应性。您可能希望显示一个进度条,并让用户有机会中止进程。如果在主线程中运行冗长的进程,则很难做到这一点。通过调用循环中的某个地方,将动态处理消息队列,这是一个肮脏的解决方法。但是在使用此解决方案时,您应该非常小心地禁用UI按钮,否则您的用户可能会多次(递归地)启动流程,或者更改流程所依赖的其他一些状态

有点离题,但变量的名称表明您正在尝试计算一个漫长过程中的间隔数?请注意,如果长进程在窗体的主线程中运行,计时器的勾号事件将在消息循环中排队,并且只有在长进程完成其工作并恢复消息处理后才会执行。您在带有DateTime字段的注释中提到的方法比使用计时器更简单、更安全、更好


当您需要一个计时器,当点击勾号时,它将立即执行代码,您可以使用而不是。如果需要从多个线程控制它,请改用(该线程是线程安全的)。请注意,这些计时器将在不同的线程中执行其事件。还要注意的是,除了窗体主线程外,您不应该从其他线程操作控件或窗体。一种简单的方法是使用该方法将其内置到框架中,然后使用消息循环对操作进行排队。

像这样的大多数问题都与编码相关,为什么不显示怀疑挂起的代码呢。有多少线程正在创建。。。调用/创建计时器的次数是多少?我已经为特定的计时器对象添加了代码。它是一个单线程,但计时器被启用和禁用多次。这段代码自最初编写(在我的时代之前)以来几乎没有被改动过。我所做的是删除timerMtimeOut.Start()和Stop()分别在timerMtimeOut.Enable=true和false之后调用。可能值得一提的是,我们有两台机器正在运行此源代码,并且应用程序在第二台机器上并没有变得无响应。我想您已经考虑过这样一个事实,即您可能正在追逐一只雁。仅仅因为你看到你的机器上发生了一些事情,而代码就是在那里被破坏的,并不一定意味着另一台机器上也发生了同样的事情。在任何情况下,是否有可能完全禁用计时器,看看问题是否在另一台机器上消失,并确定它与此相关?您的评论表明您可能已经这样做了,但还不清楚。