| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Hosting;
- using Microsoft.Extensions.Logging;
- namespace YBEE.EQM.Application;
- public class ExamSampleWorker(ILogger<ExamSampleWorker> logger, IServiceScopeFactory scopeFactory) : IHostedService, IDisposable
- {
- private readonly Dictionary<int, Task> _executingTasks = [];
- private readonly Dictionary<int, CancellationTokenSource> _cancellationTokenSources = [];
- /// <summary>
- /// StartAsync 方法不再直接启动任务,而是保持服务初始化
- /// </summary>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- public Task StartAsync(CancellationToken cancellationToken)
- {
- logger.LogInformation("抽样执行服务已初始化");
- return Task.CompletedTask;
- }
- /// <summary>
- /// 外部控制:通过参数启动后台任务
- /// </summary>
- /// <param name="examPlanId">监测计划ID</param>
- /// <returns></returns>
- public int StartTask(int examPlanId)
- {
- if (_executingTasks.TryGetValue(examPlanId, out Task value) && !value.IsCompleted)
- {
- logger.LogInformation("监测计划ID:{examPlanId},执行中,不能重复启动!", examPlanId);
- return -1;
- }
- logger.LogInformation("监测计划ID:{examPlanId},开始执行...", examPlanId);
- var cancellationTokenSource = new CancellationTokenSource();
- var executingTask = ExecuteAsync(examPlanId, cancellationTokenSource.Token);
- // 保存任务和取消令牌源,以便可以后续控制
- _executingTasks[examPlanId] = executingTask;
- _cancellationTokenSources[examPlanId] = cancellationTokenSource;
- return 0;
- }
- /// <summary>
- /// 外部控制:通过任务参数停止任务
- /// </summary>
- /// <param name="examPlanId"></param>
- /// <returns></returns>
- public int StopTask(int examPlanId)
- {
- if (!_executingTasks.TryGetValue(examPlanId, out Task value) || value.IsCompleted)
- {
- logger.LogInformation("监测计划ID:{examPlanId},未运行!", examPlanId);
- return -1;
- }
- logger.LogInformation("监测计划ID:{examPlanId},开始停止...", examPlanId);
- // 停止任务
- _cancellationTokenSources[examPlanId]?.Cancel();
- _executingTasks.Remove(examPlanId);
- _cancellationTokenSources.Remove(examPlanId);
- return 0;
- }
- /// <summary>
- /// 任务执行逻辑
- /// </summary>
- /// <param name="examPlanId"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- private async Task ExecuteAsync(int examPlanId, CancellationToken cancellationToken)
- {
- try
- {
- while (!cancellationToken.IsCancellationRequested)
- {
- using var scope = scopeFactory.CreateScope();
- var services = scope.ServiceProvider;
- var examSampleService = services.GetService<IExamSampleService>();
- await examSampleService.ExecuteSampleByExamPlanId(examPlanId);
- logger.LogInformation("监测计划ID:{examPlanId},执行完成。", examPlanId);
- StopTask(examPlanId);
- }
- }
- catch (TaskCanceledException)
- {
- logger.LogInformation("监测计划ID:{examPlanId},已取消。", examPlanId);
- }
- }
- public Task StopAsync(CancellationToken cancellationToken)
- {
- // 停止所有正在运行的任务
- foreach (var key in _executingTasks.Keys.ToList())
- {
- StopTask(key);
- }
- return Task.CompletedTask;
- }
- public void Dispose()
- {
- foreach (var cancellationTokenSource in _cancellationTokenSources.Values)
- {
- cancellationTokenSource?.Dispose();
- }
- }
- }
|