使用定时器间隔与任务延迟的重复任务

Man*_*y D 11 c#

我正在实施像方法这样的预定工作,并且已经缩小到方法的范围。一个实现定时器间隔,另一个基于任务延迟。

我也考虑过使用 Azure Timer 触发的 webjobs,但它们在多实例模式下不起作用。实际上,在多实例应用程序中,只有一个触发器在其中一个实例中被触发,而其他触发器被锁定,因此增加我的应用程序的实例计数并不会增加触发的事件数量。

方法A(定时器间隔)

using System;
using System.Threading.Tasks;
using System.Timers;

public class Example
{
    public static void Main()
    {
        var aTimer = new Timer();
        aTimer.Interval = 5000;
        aTimer.Elapsed += OnTimedEventA;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;

        var bTimer = new System.Timers.Timer();
        bTimer.Interval = 2000;
        bTimer.Elapsed += OnTimedEventB;
        bTimer.AutoReset = true;
        bTimer.Enabled = true;

        Console.WriteLine("Press the Enter key to exit the program at any time... ");
        Console.ReadLine();
    }
    private static void OnTimedEventA(Object source, System.Timers.ElapsedEventArgs e)
    {
        Task.Run(() =>
        {
            Console.WriteLine("The Elapsed event A was raised at {0}", DateTime.Now);
        });
    }
    private static void OnTimedEventB(Object source, System.Timers.ElapsedEventArgs e)
    {
        Task.Run(() =>
        {
            Console.WriteLine("The Elapsed event B was raised at {0}", DateTime.Now);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

方法 B(任务延迟)

using System;
using System.Threading.Tasks;
public class Example
{
    public static void Main()
    {
        EventAAsync();
        EventBAsync();

        Console.WriteLine("Press the Enter key to exit the program at any time... ");
        Console.ReadLine();
    }
    private static async Task EventAAsync()
    {
        while (true)
        {
            Task.Run(() =>
            {
                Console.WriteLine("The Elapsed event A was raised at {0}", DateTime.Now);
            });
            await Task.Delay(TimeSpan.FromSeconds(5));
        }
    }
    private static async Task EventBAsync()
    {
        while (true)
        {
            Task.Run(() =>
            {
                Console.WriteLine("The Elapsed event B was raised at {0}", DateTime.Now);
            });
            await Task.Delay(TimeSpan.FromSeconds(2));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

方法 A 和方法 B 在功能上都是一样的。它们都以 5 秒和 2 秒的固定间隔调用火灾事件 A 和 B,然后忘记。现在我试图了解这两种方法的优缺点。最后,事件本身在不同的线程上运行。理论上和实践中应该采用这两者中的哪一个来处理要跨多个实例扩展的许多此类事件触发器。

也欢迎任何其他方法。

Shi*_*nva 10

当您必须定期触发某些任务时,使用方法 A。当您必须在某些任务的触发之间给出固定的时间间隔时,使用方法 B。

如果事件处理程序(在触发器之后执行的任务)需要更长的时间来处理,则存在差异。

方法 A: 无论事件处理程序中的任务花费多少时间,事件处理程序都会在设置的时间间隔内不断被触发(代码必须是可重入的)。

方法B: 任务完成然后我们睡觉。所以如果任务需要不同的时间来完成,下一次触发也是在不同的时间

  • @ManikantaReddyD Task.Run 或 Task.Delay 只是将要在线程池中的线程上运行的工作项排队。想一想线程池中的线程用完的情况(可能是您的事件代码需要很长时间才能完成)。您的工作项开始排队。 (2认同)