timer - 在 Compact Framework 中使用 System.Threading.Timer

标签 timer compact-framework

我在 CF 项目 (Windows Embedded CE 6.0)、VS2005 C#、.NET 2.0 中使用 System.Threading.Timer。 这个计时器是需要的,因为像这样使用时不可能重入:

    private System.Threading.Timer mainTimer;

    private void MainForm_Load(object sender, EventArgs e)
    {
        // other initializations
        mainTimer = new System.Threading.Timer(new TimerCallback(timerMain_Tick),
                null, 100, Timeout.Infinite);
    }

也就是说,使用了 dueTime 参数,但没有使用 period 参数。只要 period 为 Timeout.Infinite,计时器就会只触发一次。通过检查表单的 InvokeRequired 属性,使计时器成为线程安全的。请注意检查是否为空。这与我的问题有关,我很快就会回答这个问题。

    private void timerMain_Tick(object stateInfo)
    {
        if (mainTimer != null)
        {
            if (this.InvokeRequired)
            {
                this.Invoke((ThreadStart)delegate
                {
                    TimerProcess();
                });
            }
            else
            {
                TimerProcess();
            }
        }
    }

计时器在退出之前必须自行重新启动。

    private void TimerProcess()
    {
        try
        {
                // do work here
        }
        finally
        {
            // retrigger
            mainTimer.Change(mainTimerInterval, Timeout.Infinite);
        }
    }

我遇到的问题是优雅地停止这该死的事情。

    private void MainForm_Closing(object sender, CancelEventArgs e)
    {
        // shut down timer
        mainTimer.Change(Timeout.Infinite, Timeout.Infinite);
        mainTimer.Dispose();
        mainTimer = null;
    }

大约 10 次中有 3 次,计时器无论如何都会触发,并且我收到“对象处置”错误。计时器代码尝试在检查 null 后调用计时器方法。 我怀疑计时器触发了,并且在表单关闭时其线程被挂起。我尝试了状态机枚举:

正常状态运行

Form_Closing 设置停止状态并在 Thread.Sleep() 循环中等待停止状态

计时器看到停止并设置停止状态(而不是重新触发自身)

我遇到的问题是计时器线程不会抢占表单关闭方法,因此陷入无限循环。 如何解决这个问题?请注意,在 CF 中,没有 Dispose(WaitHandle) 方法。

最佳答案

有趣的问题。 Compact Framework 中的 Timer 选项似乎不多。

我不确定您的特定代码是如何工作的,因此添加单个静态 bool 值可能会也可能不会解决您的问题。

以下是我如何更改您的代码以接受 timerOK 值。如果这不能解决您的问题,它可以为您提供解决此问题的想法。

private static bool timerOK;
private static long mainTimerInterval = 200;
private System.Threading.Timer mainTimer;

private void MainForm_Load(object sender, EventArgs e) {
  timerOK = true;
  mainTimer = new System.Threading.Timer(new TimerCallback(timerMain_Tick), null, 100, Timeout.Infinite);
}

private void MainForm_Closing(object sender, CancelEventArgs e) {
  timerOK = false;
  mainTimer.Change(Timeout.Infinite, Timeout.Infinite);
  mainTimer.Dispose();
  mainTimer = null;
}

private void timerMain_Tick(object stateInfo) {
  if (timerOK && (mainTimer != null)) {
    if (this.InvokeRequired) {
      this.Invoke((ThreadStart)delegate {
        TimerProcess();
      });
    } else {
      TimerProcess();
    }
  }
}

private void TimerProcess() {
  if (!timerOK) return;
  try {
    // do work here
  } finally {
    // retrigger
    mainTimer.Change(mainTimerInterval, Timeout.Infinite);
  }
}

关于timer - 在 Compact Framework 中使用 System.Threading.Timer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17034568/

相关文章:

java - 特定日期和时间的倒计时器

go - 我们应该停止这种 Ticker 吗?

variables - IRC 变量剩余时间

c# - 来自 .NET Compact Framework 3.5 应用程序的随机 native 异常

C# - 覆盖系统命名空间中可用的一些类

c# - 如果不能命名互斥锁,它有什么用?

.net - .NET Compact Framework 应用程序是否与 Windows Phone 7 兼容?

java - 定时器内存泄漏

windows - .Net Compact Framework,如何在windows下 "use"(测试目的)

c - 定时器的用户级中断处理程序