当前位置: 首页 > 知识库问答 >
问题:

. net Core上的计划任务

邴俊友
2023-03-14

我需要使用将widows服务器的Scheduler任务中的几个计划任务转换为一个独立的应用程序。网

在过去,我用过石英。Net框架4。x、 基于不同调度器的多个长时间运行的任务存在一些小问题。

现在我正在使用。Net 5,我想知道是否有一种新的方式来安排任务,比如worker服务,或者使用Quartz更好、更灵活。网

因为我需要运行长时间的任务,从30到2小时,我需要创建一个定时的后台任务,使用系统。线程。定时器

代码应如下所示:

    public Task StartAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Timed Hosted Service running.");

        _timer = new Timer(DoSomething, null, TimeSpan.Zero, 
            TimeSpan.FromHours(24));

        return Task.CompletedTask;
    }

它应该每24小时调用DoSomething。

我的疑问是:

  • 当我第一次运行应用程序时,它什么时候开始工作并计算24小时

共有1个答案

陶朝明
2023-03-14

当我第一次运行应用程序时,它什么时候开始工作并计算24小时?

对设置断点并启动应用程序。你会看到它开火的速度有多快。

员工服务是否适合管理计划任务?

我怎么能说任务必须在一天中的特定时间运行,例如午夜?

让我们看看这个代码:

public sealed class MyTimedBackgroundService : BackgroundService
{

    private static int SecondsUntilMidnight()
    {
        return (int)(DateTime.Today.AddDays(1.0) - DateTime.Now).TotalSeconds;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        var countdown = SecondsUntilMidnight();

        while (!stoppingToken.IsCancellationRequested)
        {
            if (countdown-- <= 0)
            {
                try
                {
                    await OnTimerFiredAsync(stoppingToken);
                }
                catch(Exception ex)
                {
                    // TODO: log exception
                }
                finally
                {
                    countdown = SecondsUntilMidnight();
                }
            }
            await Task.Delay(1000, stoppingToken);
        }
    }

    private async Task OnTimerFiredAsync(CancellationToken stoppingToken)
    {
        // do your work here
        Debug.WriteLine("Simulating heavy I/O bound work");
        await Task.Delay(2000, stoppingToken);
    }
}

这不使用系统。穿线。计时器如果你担心计时器因为某些边界而没有真正启动,那就不要担心。有些人对此心存疑虑。我从来没有遇到过这种事。我经常用定时器来做这类工作。

它将计算午夜前的秒数,然后循环直到到达。

这是一个不可重入定时器,由于处理延迟的业务逻辑,会有轻微的时间延迟。

下面是另一个使用System.线程. Timer的示例:

public sealed class MyTimedBackgroundService : IHostedService
{
    private Timer _t;

    private static int MilliSecondsUntilMidnight()
    {
        return (int)(DateTime.Today.AddDays(1.0) - DateTime.Now).TotalMilliseconds;
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        // set up a timer to be non-reentrant
        _t = new Timer(async _ => await OnTimerFiredAsync(cancellationToken),
            null, MilliSecondsUntilMidnight(), Timeout.Infinite);
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _t?.Dispose();
        return Task.CompletedTask;
    }

    private async Task OnTimerFiredAsync(CancellationToken cancellationToken)
    {
        try
        {
            // do your work here
            Debug.WriteLine("Simulating heavy I/O bound work");
            await Task.Delay(2000, cancellationToken);
        }
        finally
        {
            // set timer to fire off again
            _t?.Change(MilliSecondsUntilMidnight(), Timeout.Infinite);
        }
    }
}

(此代码未经测试,可能存在一些拼写/语法错误)

这是一个非重入定时器,这意味着如果它当前正在处理数据,您可以保证它不会再次启动。

它将计算午夜前的毫秒数,然后根据该计算设置计时器。

这个想法来自微软。

这两个示例都可以如此注入:

services.AddHostedService<MyTimedBackgroundService>();

云本机警告:

请记住,由于这些示例是应用程序的本地示例,如果应用程序在有多个实例运行的情况下水平扩展,您将在单独的进程中运行两个或多个计时器。只是一个友好的提醒。如果应用程序永远无法扩展,请忽略此警告。

 类似资料:
  • 计划任务系统使用说明 新版计划任务为用户提供了以下功能 创建一个计划任务 修改一个计划任务 删除计划任务 查看一个namespace的所有计划任务 查看一个namespcae的某个计划任务详细内容 查看一个计划任务的执行状况 查看任务的日志 查看创建的计划任务列表和某个计划任务的详细信息。 点击计划任务v2,进入计划任务列表,在这里可以看到用户名下的所有计划任务,点击一个计划任务,可以看到该计划任

  • 我们有一个Spring Boot应用程序,并有计划的任务。 我们希望在多个服务器上部署我们的应用程序,因此将有多个应用程序实例。 如何将 Spring 配置为仅在指定的服务器上运行计划任务?

  • 亚马逊宣布了AWS Lambda(http://AWS.Amazon.com/Lambda/)。 产品说明包括: 计划任务 AWS Lambda函数可以由外部事件计时器触发,因此可以在定期计划的维护时间或非高峰时段运行函数。例如,您可以触发一个AWS Lambda函数,在非繁忙时间执行每晚的存档清理。 当我读到这篇文章时,我明白了我终于可以有一种方法来始终如一地完成“类似朋党”的任务。我想每天下午

  • 我们有一个程序,客户声称文件没有在应该生成的时候生成,只是在一天中很晚才出现。 我想知道这是否是因为任务调度程序的安排。 任务计划在每天下午12:23开始,然后无限期地每5分钟执行一次。 考虑到日程安排,并将其设置为每天运行,在00:00:00-12:23:00的时间内会发生什么? 前一天的日程是否因为“无限期”的设定而一直运行到第二天? 或者,由于任务设置为每天运行,前一天的计划是否在00:00

  • 我已经创建了一个控制台应用程序,并尝试在任务计划程序中运行。当我通过单击可执行文件或使用快捷方式运行它时,它工作正常,但当我在任务调度程序中运行它时,我得到“PHLIP231 Prod的应用程序访问路径' C:\WINDOWS\DMBErrors '被拒绝。” 我已经在我的应用程序中搜索了此路径,甚至尝试手动将路径添加到我的计算机,但没有成功。我的应用程序构建了一个excel文件并将其写入相对于可

  • > 我需要在执行前一个任务后以不同的延迟一个接一个地运行计划的任务。示例。有一个任务列表和延迟列表。 现在我需要运行task1通过100ms,task2在task1之后通过9ms,task3在task2之后通过22ms等等。 我正在使用javafx。任务可以使用一些UI更新方法,例如更改节点位置。这迫使我使用平台。runLater()方法,因为如果不这样做,则会出现异常“Not on FX app