using System.Diagnostics; using ConsoleApp2.Const; using ConsoleApp2.Services; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace ConsoleApp2.HostedServices; /// /// 任务监控 /// public class TaskMonitorService : BackgroundService { private readonly IHostApplicationLifetime _lifetime; private readonly ILogger _logger; private readonly ProcessContext _context; private readonly DataRecordQueue _producerQueue; private readonly DataRecordQueue _consumerQueue; public TaskMonitorService(IHostApplicationLifetime lifetime, ILogger logger, ProcessContext context, [FromKeyedServices(ProcessStep.Producer)] DataRecordQueue producerQueue, [FromKeyedServices(ProcessStep.Consumer)] DataRecordQueue consumerQueue) { _lifetime = lifetime; _logger = logger; _context = context; _producerQueue = producerQueue; _consumerQueue = consumerQueue; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Factory.StartNew(Monitor, stoppingToken); } private async Task Monitor() { var sw = Stopwatch.StartNew(); var lastTime = sw.ElapsedMilliseconds; var lastInputCount = _context.InputCount; var lastTransformCount = _context.TransformCount; var lastOutputCount = _context.OutputCount; bool endCheck = false; while (true) { EndCheck: // var running = 0; // var error = 0; // var completed = 0; // var canceled = 0; // foreach (var task in _taskManager.Tasks) // { // switch (task.Status) // { // case TaskStatus.Canceled: // canceled++; // break; // case TaskStatus.Faulted: // error++; // break; // case TaskStatus.RanToCompletion: // completed++; // break; // default: // running++; // break; // } // } var time = sw.ElapsedMilliseconds; var inputCount = _context.InputCount; var transformCount = _context.TransformCount; var outputCount = _context.OutputCount; var elapseTime = (time - lastTime) / 1000f; var inputSpeed = (inputCount - lastInputCount) / elapseTime; var transformSpeed = (transformCount - lastTransformCount) / elapseTime; var outputSpeed = (outputCount - lastOutputCount) / elapseTime; // _logger.LogInformation( // "Task monitor: running: {Running}, error: {Error}, completed: {Completed}, canceled: {Canceled}, outputSpeed: {Speed} records/s", // running, error, completed, canceled, outputSpeed); _logger.LogInformation( "Process monitor: input: {inputStatus}, transform: {transformStatus}, output: {outputStatus}\nInput: {InputCount}, Transform: {TransformCount}, Output: {OutputCount}", _context.IsInputCompleted ? "completed" : $"running {inputSpeed:F2} records/s", _context.IsTransformCompleted ? "completed" : $"running {transformSpeed:F2} records/s", _context.IsOutputCompleted ? "completed" : $"running {outputSpeed:F2} records/s", inputCount, transformCount, outputCount); _logger.LogInformation("Queue monitor: producer queue: {ProducerQueue}, consumer queue: {ConsumerQueue}", _producerQueue.Count, _consumerQueue.Count); await Task.Delay(5000); lastTime = time; lastInputCount = inputCount; lastTransformCount = transformCount; lastOutputCount = outputCount; if (_context is { IsInputCompleted: true, IsTransformCompleted: true, IsOutputCompleted: true }) { if (!endCheck) { endCheck = true; goto EndCheck; } break; } } _logger.LogInformation("***** All tasks completed *****"); _logger.LogInformation("***** ElapseTime: {Time}", (sw.ElapsedMilliseconds / 1000f).ToString("F3")); // _lifetime.StopApplication(); } }