如何在IHostedService实现中动态修改定时任务的函数参数?
解决方案:实现定时任务参数动态递增
要实现首次调用GetProductsInfo传入0,后续每次调用参数递增10的需求,只需在类中添加变量跟踪当前参数值,并处理线程安全问题即可。以下是修改后的完整代码:
using Timer = System.Timers.Timer; public class GetProductsEvent : IHostedService, IDisposable { private readonly int _seconds; private readonly Timer _timer; private readonly IServiceProvider _serviceProvider; // 跟踪当前参数值,初始为0 private int _currentStartRow = 0; // 线程安全锁,避免多线程下参数递增出错 private readonly object _lockObj = new object(); public GetProductsEvent(IServiceProvider serviceProvider, EventConfiguration eventConfig) { _seconds = eventConfig.SendInvoiceTimer; _timer = new Timer(GetTimePeriod()); _timer.Elapsed += Timer_Elapsed; _serviceProvider = serviceProvider; } private void Timer_Elapsed(object sender, ElapsedEventArgs e) { int currentValue; // 加锁保证参数读取和递增的原子性 lock (_lockObj) { currentValue = _currentStartRow; _currentStartRow += 10; } DoWork(currentValue); } private void DoWork(int startRow) { try { using var scope = _serviceProvider.CreateScope(); { IHostWorker worker = scope.ServiceProvider.GetRequiredService<IHostWorker>(); worker.GetProductsInfo(startRow); } } catch (Exception) { // Logging } _timer.Interval = GetTimePeriod(); _timer.Start(); } private double GetTimePeriod() { var runTime = DateTime.Now.AddSeconds(_seconds); return (runTime - DateTime.Now).TotalMilliseconds; } public void Dispose() { // TODO release managed resources here _timer.Stop(); _timer?.Dispose(); } public async Task StartAsync(CancellationToken cancellationToken) { _timer.AutoReset = false; _timer.Start(); } public async Task StopAsync(CancellationToken cancellationToken) { _timer.Stop(); } }
关键改动说明:
- 添加
_currentStartRow变量:存储当前要传入GetProductsInfo的参数值,初始值设为0,满足首次调用要求。 - 添加
_lockObj锁对象:由于System.Timers.Timer的Elapsed事件在ThreadPool线程触发,若定时器间隔过短可能出现多线程并发执行的情况,加锁可保证参数读取和递增操作的原子性,避免数值错乱。 - 修改
Timer_Elapsed方法:不再固定传入0,而是先读取当前参数值,再将参数递增10,确保每次调用的参数符合递增规则。
内容的提问来源于stack exchange,提问作者Majid821
相关产品推荐
相关产品推荐

