using Common.AspNetCore.Extensions; using Common.Frame.Services.Cache.Interfaces; using Common.NETCore.Utility; using FASS.Scheduler.Models; using FASS.Scheduler.Services.CronTasks; using FASS.Scheduler.Services.EventBus; using FASS.Scheduler.Services.Extends; using FASS.Scheduler.Utility; using FASS.Service.Dtos.Setting; namespace FASS.Scheduler.Services { public class AppHostService : IHostedService, IAsyncDisposable { private IHostApplicationLifetime Lifetime { get; } private CancellationTokenSource? _startupTokenSource; private Task? _startupTask; public ILogger Logger { get; } public AppSettings AppSettings { get; } public IServiceProvider ServiceProvider { get; } public ExtendService ExtendService { get; private set; } = null!; public EventBusService EventBusService { get; private set; } = null!; public CronTaskService CronTaskService { get; private set; } = null!; public AppHostService( IHostApplicationLifetime lifetime, ILogger logger, AppSettings appSettings, IServiceProvider serviceProvider) { Lifetime = lifetime; Logger = logger; AppSettings = appSettings; ServiceProvider = serviceProvider; Lifetime.ApplicationStarted.Register(OnApplicationStarted); } public Task StartAsync(CancellationToken cancellationToken) { Logger.LogInformation("服务启动中"); return Task.CompletedTask; } public async Task StopAsync(CancellationToken cancellationToken) { Logger.LogInformation("服务停止中"); var startupTokenSource = Interlocked.Exchange(ref _startupTokenSource, null); startupTokenSource?.Cancel(); var startupTask = Interlocked.Exchange(ref _startupTask, null); if (startupTask is not null) { try { await startupTask.WaitAsync(cancellationToken); } catch (OperationCanceledException) when (startupTokenSource?.IsCancellationRequested == true || cancellationToken.IsCancellationRequested) { Logger.LogInformation("服务启动流程已取消"); } catch (Exception ex) { Logger.LogError(ex, "服务等待启动流程结束失败"); } } startupTokenSource?.Dispose(); var stopTasks = new List(); if (CronTaskService is not null) { stopTasks.Add(CronTaskService.StopAsync(cancellationToken)); } if (EventBusService is not null) { stopTasks.Add(EventBusService.StopAsync(cancellationToken)); } if (ExtendService is not null) { stopTasks.Add(ExtendService.StopAsync(cancellationToken)); } await Task.WhenAll(stopTasks); } public async ValueTask DisposeAsync() { Logger.LogInformation("服务释放资源"); } private void OnApplicationStarted() { if (_startupTask is not null) { return; } _startupTokenSource = new CancellationTokenSource(); _startupTask = RunStartupAsync(_startupTokenSource.Token); } private async Task RunStartupAsync(CancellationToken cancellationToken) { try { Logger.LogInformation("[{Name} V {Version}]", Session.AssemblyName.Name, Session.AssemblyName.Version); if (AppSettings.Scheduler.StartupDueTime > 0) { Logger.LogInformation("启动延迟:{Delay} 毫秒", AppSettings.Scheduler.StartupDueTime); await Task.Delay(AppSettings.Scheduler.StartupDueTime, cancellationToken); } Logger.LogInformation("--------初始化--------"); InitializeCache(); InitializeService(); Logger.LogInformation("--------启动--------"); await Task.WhenAll( ExtendService.StartAsync(cancellationToken), EventBusService.StartAsync(cancellationToken), CronTaskService.StartAsync(cancellationToken)); } catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { Logger.LogInformation("--------取消--------"); } catch (Exception ex) { Logger.LogCritical(ex, "错误"); } } public void InitializeCache() { ServiceProvider.GetScopeService().GetConfigToDto(CacheKey.Setting.ConfigService); } public void InitializeService() { ExtendService = ServiceProvider.GetRequiredService(); EventBusService = ServiceProvider.GetRequiredService(); CronTaskService = ServiceProvider.GetRequiredService(); } } }