system.Threading.Timer没有开始?
-
13-12-2019 - |
题
我正在使用c#compact framework 2,sp2。
设备的操作系统已设置为使用我的应用程序启动,让我们调用应用程序“Loader.exe”。
加载程序简而言之:一个纯粹的形式,如有必要,显示整个加载状态消息(Layman的术语)出错以及“启动应用程序[XYZ]”)和状态机运行在背景中显示基本全屏表单。
因此加载程序的表单的构造函数在非常结束时具有以下内容:try
{
label1.Text = "Starting GUI Init Thread..."; //debug only message
System.Threading.Timer guiInit = new System.Threading.Timer(
RunStateMachine, null, 2000, System.Threading.Timeout.Infinite
);
//callback: RunStateMachine, null argument
//initial callback is 2000ms from this point, and doesn't run again.
}
catch (Exception ex1)
{
label1.Text = "GUI Init Error 2";
Failure_Label.Text = ex1.Message;
}
.
和“runstatemachine”在不同的螺纹上工作,允许表单显示,并且任何时间runstatemachine需要与表单交互,例如更新消息,我调用了(this.invokerequired的函数){this.invoke(...);} else {...}
所以,我的问题?
间歇性地,我的程序将挂起,它是因为计时器没有触发回调。我在上面的尝试块中添加了调试消息,以及许多其他地方告诉我它在哪里挂起,包括在“runstatemachine”开始时的消息。最终,我的程序挂在消息“开始GUI Init Thread ...”
这告诉我线程计时器没有运行一个时间我需要它。
我的理论是在计时器触发回调之前收集的垃圾。这意味着计时器是全球性的,然后在我到达runstatemachine时明确地处理,即它将完美地运行......但我不想认为我已经解决了它只是为了从现在开始一个月间歇地出现这个。
思想?
解决方案
我的理论是它在计时器之前收集的垃圾 触发回调。这将意味着计时器是全球性的,而且 然后在进入runstatemachine时明确地处理,它将 完美地运行......但我不想认为我已经解决了它 从现在开始,这个月间歇地出现。
看起来你想要确认这是你的问题。是的,这是问题。
计时器存储在局部变量中,从未使用过。这使得GC有资格。计时器的GC'ing导致最终确定导致定时器被禁用。
我建议您将计时器存储在表单类的实例字段中,并在回调后从那里删除它。