在每个月月底启动计时器 c#

问题描述 投票:0回答:2

我需要在每个月底启动一个计时器。 我编写了一个小程序,其中的代码需要在每个月的最后一天执行,但我不知道如何实现它。我向我的老板建议使用 Windows 调度程序,但他希望用带有计时器的代码来完成。

那么我该怎么做呢?

c# timer
2个回答
1
投票

我成功说服老板使用windows计划任务。有一种方法可以用计时器来做到这一点。我在下面包含了代码。它又快又脏。强烈注意,使用计划任务是实现此类任务的正确方法。

    private Timer timer;

    public MyClass()
    {
        timer = new Timer();
        timer.Elapsed += TimerElapsed;
    }

    private void TimerElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
    {

        if (DateTime.Now.Day == DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month))// is it the last day of this month
        {
            ClientStatsController.FireAll();
        }

        Thread.Sleep(TimeSpan.FromMinutes(5));
        timer.Interval = CalculateInterval();
        TimeSpan interval = new TimeSpan(0, 0, 0, 0, (int)timer.Interval);

    }

    // Helper functions
    private static TimeSpan From24HourFormat(string value)
    {
        int hours = Convert.ToInt32(value.Substring(0, 2));
        int mins = Convert.ToInt32(value.Substring(2, 2));

        return TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(mins);
    }

    private double CalculateInterval()
    {
        string runtimeValue = ConfigController.AppSettings["runTime"]; // just a simple runtime string like 0800
        double runTime = From24HourFormat(runtimeValue).TotalMilliseconds;
        if (DateTime.Now.TimeOfDay.TotalMilliseconds < runTime)
        {
            return runTime - DateTime.Now.TimeOfDay.TotalMilliseconds;
        }
        else
        {
            return (From24HourFormat("2359").TotalMilliseconds - DateTime.Now.TimeOfDay.TotalMilliseconds) + runTime;
        }
    }

编辑

我开始回顾所有以前的问题和答案。

使用计时器是一个非常糟糕的主意。对于计划任务,您需要完全使用它。一个调度程序。 Windows提供了一个不错的任务调度程序,但是如果你有更复杂的调度逻辑和后台任务,最好使用合适的第三方库。

.NET 的两个杰出的产品是 Hangfire 和 Quartz。

Hangfire 配有仪表板,并且非常容易实现,特别是如果您在 .NET 核心平台上工作。

Quartz也是一个非常不错的解决方案,它比Hangfire有更多的调度选项,更适合复杂的调度逻辑。

提出的解决方案确实非常糟糕,来自一个刚开始工作的实习生。我很高兴回到过去并意识到如何可以以不同的方式更好地完成事情。


0
投票

这里有一种更简单的方法,可以让您的作业仅在该月的最后一天运行。

// Set timer to run every 24hrs
new Timer(RunJobMethod, null, 0, (int)TimeSpan.FromHours(24).TotalMilliseconds);

将以下代码添加到您的 RunJobMethod

// Enforce it only runs on the last day of the month
var currentMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
var nextMonth = currentMonth.AddMonths(1);
var lastDay = nextMonth.AddDays(-1);
if (DateTime.Now.Day != lastDay.Day || DateTime.Now.Month != lastDay.Month || DateTime.Now.Year != lastDay.Year)
    return;
© www.soinside.com 2019 - 2024. All rights reserved.