c# 实现每个整数分钟执行一次的定时任务

StartAsync 方法中,计算了下一个整数分钟的时间,然后使用 System.Threading.Timer 类创建定时器,并将首次触发时间设为该时间。在 InsertDB2Async 方法中,我们定义了要执行的操作,然后使用 await Task.Delay(1000) 模拟异步操作的等待时间。最后,我们重新计算下一个整数分钟的时间,并使用 Change 方法设置定时器的下一次触发时间。

需要注意的是,InsertDB2Async 方法是异步方法,但是我们使用的是 async void 定义方法。在实际应用中,应该使用 async Task 定义异步方法,以避免出现无法捕获的异常。另外,System.Threading.Timer 类的回调方法是在另一个线程上执行的,因此在操作期间需要注意线程安全。

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;

public class MyTimerHostedService : IHostedService, IDisposable
{
    private Timer _timer;

    public Task StartAsync(CancellationToken cancellationToken)
    {
        // 计算下一个整分钟的时间,并设置定时器的首次触发时间
        var now = DateTime.Now;
        var nextMinute = now.AddMinutes(1);
        var target = nextMinute.AddSeconds(-nextMinute.Second);
        var delay = (int)(target - now).TotalMilliseconds;
        _timer = new Timer(InsertDB2Async, null, delay, 60000);
        return Task.CompletedTask;
    }

    private async void InsertDB2Async(object state)
    {
        try
        {
            // 在这里写你要执行的代码
            Console.WriteLine($"[{DateTime.Now}] Hello, world!");
            // 等待异步操作完成
            await Task.Delay(1000);
        }
        finally
        {
            // 计算下一个整分钟的时间,并设置定时器的下一次触发时间
            var now = DateTime.Now;
            var nextMinute = now.AddMinutes(1);
            var target = nextMinute.AddSeconds(-nextMinute.Second);
            var delay = (int)(target - now).TotalMilliseconds;
            _timer.Change(delay, 60000);
        }
    }

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

    public void Dispose()
    {
        _timer.Dispose();
    }
}

  1. 使用Task.Delay方法的重载版本,将等待时间和取消标志作为参数传入,可以及时响应取消请求。

  2. 使用CancellationToken.Register方法注册取消回调函数,避免忘记取消定时器。

  3. 将计算下一个整分钟的时间的代码封装为一个单独的方法,提高代码复用性。

public class MyTimerHostedService : IHostedService, IDisposable
{
    private Timer _timer;
    private CancellationTokenSource _cts;

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _cts = new CancellationTokenSource();
        _timer = new Timer(async state =>
        {
            try
            {
                // 在这里写你要执行的代码
                Console.WriteLine($"[{DateTime.Now}] Hello, world!");
                // 等待异步操作完成
                await Task.Delay(GetDelayTime(), _cts.Token);
            }
            finally
            {
                // 重新设置定时器的下一次触发时间
                _timer.Change(GetDelayTime(), Timeout.Infinite);
            }
        }, null, GetDelayTime(), Timeout.Infinite);
        cancellationToken.Register(() =>
        {
            _cts.Cancel();
            _timer.Dispose();
        });
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _cts.Cancel();
        _timer.Dispose();
        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _cts.Dispose();
        _timer.Dispose();
    }

    private TimeSpan GetDelayTime()
    {
        var now = DateTime.Now;
        var nextMinute = now.AddMinutes(1);
        var target = nextMinute.AddSeconds(-nextMinute.Second);
        return target - now;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值