4

我的 System.Threading.Timer (具有回调)永远不会可靠地触发。这是我的编程任务的一部分,我在其中输入计时器应该从文本框中运行的时间量。

定时器声明如下:

System.Threading.Timer timer = new System.Threading.Timer(WorkerObject.callback, null, delay, Timeout.Infinite);

延迟只是int描述回调第一次触发的延迟(它应该只触发一次)。

回调方法是这样的:

 public static void callback(Object stateinfo)
 {
     stop = true;
 }

所做的只是将标志设置为 true 以停止循环(由 ThreadPool 上的线程运行,实际上是停止线程)。

循环如下所示:

while (!stop)
{
    currentTextbox.Invoke(new Action(delegate()
    {
        currentTextbox.AppendText((counter++) + Environment.NewLine);
        currentTextbox.Update();
     }));
}

我的问题是stop对于超过 5000 毫秒的任何延迟,该变量始终为假。有没有办法“强制”回调始终触发?

4

3 回答 3

12

您需要保留对计时器的引用。

计时器对象很可能正在被垃圾收集,这将运行其终结器,停止计时器。

因此,只要您需要计时器处于活动状态,请保持参考。

于 2013-09-23T21:43:35.990 回答
5

我建议使用CancellationTokenSource

static CancellationTokenSource Cancel = new CancellationTokenSource();

public static void Callback(object state)
{
    Cancel.Cancel();
}

和你的循环:

while (!Cancel.IsCancellationRequested)
{
    ...
}

这比 using 干净得多volatile,并且当您将简单的概念证明移动到单独的类时更容易移植。有关更多信息,请参阅我的博客Polling for Cancellation

于 2013-09-23T22:04:49.083 回答
1

运行时抖动可能会将您的while(!stop)条件优化为while(true). stop将变量标记为 volatile。

private volatile bool stop = false;
于 2013-09-23T21:49:43.173 回答