System.Threading.Timer没有启动?

时间:2012-10-03 15:39:43

标签: c# timer hang compact-framework2.0

我在Compact Framework 2,SP2中使用C#。

设备的操作系统设置为启动我的应用程序,让我们调用应用程序“Loader.exe。”

Loader就是这样的:一个简单的单一格式,在整个加载过程中显示状态消息,如果有必要(外行人的条件是有错误和异常消息,或者“启动应用程序[xyz]”),并且运行状态机在后台显示基本的全屏形式。

所以Loader的表单构造函数在非常结尾处有以下内容:

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”在与UI不同的线程上工作,允许表单显示,并且任何时候RunStateMachine需要与表单交互,例如更新消息,我调用一个使用if的函数(this.InvokeRequired ){this.Invoke(...);} else {...}

那么,我的问题是什么? 间歇性地,我的程序将挂起,这是因为计时器没有触发回调。我在上面的try块中添加了调试消息,以及许多其他地方告诉我它挂在哪里,包括在“RunStateMachine”的非常开始的消息。最后,我的程序挂起了“正在启动GUI初始化线程......”的消息

这告诉我线程计时器没有运行我需要的一个时间 我的理论是它在定时器触发回调之前被垃圾收集。这意味着如果计时器是全局的,然后在我到达RunStateMachine时明确处理,它将完美运行......但我不想以为只是为了在一个月后间歇性地发现这个问题。

思想?

1 个答案:

答案 0 :(得分:7)

  

我的理论是它在计时器之前被垃圾收集   触发回调。这意味着如果计时器是全局的,并且   然后在我到达RunStateMachine时明确处理,它会   运行得很完美...但我不想以为我找到它就解决了   从现在起一个月间歇性地出现。

看起来你想确认这是你的问题。 是的,这就是问题所在。

计时器存储在一个永远不会再使用的局部变量中。这使它符合GC的条件。定时器的GC'导致定型,导致定时器被禁用。

我建议您将计时器存储在表单类的实例字段中,并在回调被触发后将其从那里删除。