9

如何通过此计时器的回调函数更改 System.Threading.Timer 中的间隔?它是否正确?

这样做。没有发生。

public class TestTimer
{
    private static Timer _timer = new Timer(TimerCallBack); 

    public void Run()
    {
        _timer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(1));
    }

    private static void TimerCallBack(object obj)
    {
        if(true)
            _timer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(10));
    }

}
4

2 回答 2

13

此行生成无限递归:

if(true)
    _timer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(10));

第一个参数强制TimerCallBack立即执行。所以它会无限期地一次又一次地执行它。

修复将是

if(true)
    _timer.Change(TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10));
于 2011-05-25T05:31:03.787 回答
5

问题是您的调用Change指定下一个调用应该立即发生。如果您要Change 每次都调用,您可以使用一个句点Timeout.Infinite(它只是一个常数 -1)来告诉它在下一次之后完全避免重复 - 但它仍然会继续触发,因为下一次时间,你重置它。例如:

using System;
using System.Threading;

static class Program
{
    private static Timer timer = new Timer(TimerCallBack); 

    public static void Main()
    {
        timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(1));
        Thread.Sleep(10000);

    }

    private static void TimerCallBack(object obj)
    {
        Console.WriteLine("{0}: Fired", DateTime.Now);
        timer.Change(TimeSpan.FromSeconds(3),
                     TimeSpan.FromMilliseconds(Timeout.Infinite));
    }
}

或者,您可以只更改一次,然后离开它:

using System;
using System.Threading;

static class Program
{
    private static Timer timer = new Timer(TimerCallBack); 
    private static bool changed = false;

    public static void Main()
    {
        timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(1));
        Thread.Sleep(10000);

    }

    private static void TimerCallBack(object obj)
    {
        Console.WriteLine("{0}: Fired", DateTime.Now);
        if (!changed)
        {
            changed = true;
            TimeSpan interval = TimeSpan.FromSeconds(3);
            timer.Change(interval, interval);
        }
    }
}

请注意,在任何一种情况下都没有使用初始间隔(上面的示例中为 1 秒),因为我们会Change立即调用 - 如果您真的想要在第一次调用之前有一个不同的时间,请不要TimeSpan.Zero在初始调用中使用Change.

于 2011-05-25T05:31:59.437 回答