线程或计时器,每隔x分钟运行的最佳方式

时间:2015-10-15 20:59:20

标签: c# .net multithreading timer task

我至少有20个线程,每个线程每隔x分钟执行一些操作。我的问题是我可以使用带有间隔的计时器,我在他们的ElapsedEventHandler上注册一个委托,在那个方法中,我使用Thread或Task进行操作。顺便说一句,我可以轻松管理计时器的开始,停止和间隔

这是最好的方法吗? .NET中还有其他解决方案或其他选择吗?

例如:

List<IpeTimer> Timers = new List<IpeTimer>();

        Timers.Add(new IpeTimer(){ TimerName = "timer1" ,Timer = new System.Timers.Timer()});
        Timers[0].Timer.Interval = 4000;
        Timers[0].Timer.Elapsed += new ElapsedEventHandler(TimerEventProcessor1);
        Timers[0].Timer.Start();


        Timers.Add(new IpeTimer() { TimerName = "timer2", Timer = new System.Timers.Timer() });
        Timers[1].Timer.Interval = 5000;
        Timers[1].Timer.Elapsed += new ElapsedEventHandler(TimerEventProcessor2);
        Timers[1].Timer.Start();

public static void TimerEventProcessor1(object sender, ElapsedEventArgs e)
    {
        Task t2 = new Task(() =>
        {
            Console.WriteLine("1");
        }
        , TaskCreationOptions.LongRunning);
        t2.Start();
    }

    public static void TimerEventProcessor2(object sender, ElapsedEventArgs e)
    {
        Task t2 = new Task(() =>
        {
            Console.WriteLine("2");
        }
        , TaskCreationOptions.LongRunning);
        t2.Start();
    }

2 个答案:

答案 0 :(得分:1)

以上都不是。

使用等待Task.Delay的异步方法(内部使用Threading.Timer)。这样你等待的时间间隔将不取决于操作需要多长时间(即,如果计时器的间隔是2秒,但是运行需要1秒,那么只有一秒没有操作运行):

async Task DoSomething(CancellationToken token)
{
    while (true)
    {
        // do something
        await Task.Delay(1000, token);
    }
}

答案 1 :(得分:0)

我使用您的代码提出了这个解决方案。

    public static CancellationToken Token { get; private set; }
    public static void Cancel()
    { 
        Token = new CancellationToken(true);
    }

    async static Task DoSomething(int interval)
    {
        while (true)
        {
            Console.WriteLine("1");
            await Task.Delay(interval, Token);
        }
    }


    private static void Main(string[] args)
    {
        DoSomething(1000);
        Thread.Sleep(5000);
        Cancel();
        Console.ReadLine();
    }