Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用计时器间隔与任务延迟的重复任务_C# - Fatal编程技术网

C# 使用计时器间隔与任务延迟的重复任务

C# 使用计时器间隔与任务延迟的重复任务,c#,C#,我正在实现一个计划好的类似作业的方法,并且已经缩小到了方法的范围。一个实现计时器间隔,另一个基于任务延迟 我也考虑过使用Azure定时器触发的webjobs,但它们在多实例模式下不起作用。实际上,在多实例应用程序中,只有一个触发器在其中一个实例中被触发,其他触发器被锁定,因此增加我的应用程序的实例计数不会增加触发的事件数 方法A(计时器间隔) 方法B(任务延迟) 方法A和方法B在功能上都是相同的。 他们都以5秒和2秒的间隔将火灾事件称为A和B,然后忘记。现在我试图了解这两种方法的利弊。最后,事件

我正在实现一个计划好的类似作业的方法,并且已经缩小到了方法的范围。一个实现计时器间隔,另一个基于任务延迟

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

方法A(计时器间隔)

方法B(任务延迟)

方法A和方法B在功能上都是相同的。 他们都以5秒和2秒的间隔将火灾事件称为A和B,然后忘记。现在我试图了解这两种方法的利弊。最后,事件本身在不同的线程上运行。在理论上和实践中,应采用这两种方法中的哪一种来处理跨多个实例缩放的许多此类事件触发器


任何其他方法都是受欢迎的。

使用定时器,而两者都使用@Evk指出的相同时钟,但第一种方法永久运行定时器

使用Task.Delay将同样准确,但在完成的延迟和开始新的延迟之间有很短的差距。长时间后,它们可能会失去同步。所以5秒到2秒间隔之间的距离和开始计时的时间不一样


使用永久运行的计时器不会出现此问题。

当您必须定期触发某些任务时,将使用方法A方法B用于您必须在触发某项任务之间给出定期间隔的情况

如果事件处理程序(触发器后执行的任务)处理时间较长,则会有差异

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

方法B:
任务完成后我们就睡觉。因此,如果任务需要不同的时间来完成,下一个触发器也会在不同的时间执行。

任务。延迟
在内部使用相同的
计时器,所以选择您喜欢的任何东西。@Evk除了使用延迟外,就像一次性计时器,而不是周期性运行的计时器。一次性计时器出现问题,导致时钟随时间漂移。因此,长时间运行后,2秒和5秒的间隔将不同步。谢谢。但是在方法B中,我使用Task.run以fire and forget的方式运行了与实际事件相关的代码,那么这是否使两者都执行相同的基于间隔的调用?@ManikantaReddyD Task.run或Task.Delay只是将要在线程池中的线程上运行的工作项排队。想象一下线程池中的线程已经用完的情况(可能是事件代码需要很长时间才能完成)。您的工作项开始排队。但这可能是您的预期行为
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);
        });
    }
}
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));
        }
    }
}