diff --git a/src/ThingsGateway.Admin.NetCore/Services/ApplicationLifetime.cs b/src/ThingsGateway.Admin.NetCore/Services/ApplicationLifetime.cs new file mode 100644 index 000000000..1b897685a --- /dev/null +++ b/src/ThingsGateway.Admin.NetCore/Services/ApplicationLifetime.cs @@ -0,0 +1,88 @@ +// ------------------------------------------------------------------------------ +// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 +// 此代码版权(除特别声明外的代码)归作者本人Diego所有 +// 源代码使用协议遵循本仓库的开源协议及附加协议 +// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway +// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway +// 使用文档:https://kimdiego2098.github.io/ +// QQ群:605534569 +// ------------------------------------------------------------------------------ + +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace ThingsGateway.Admin.NetCore; + +public sealed class ApplicationLifetime : IHostApplicationLifetime +{ + private readonly CancellationTokenSource _startedSource = new CancellationTokenSource(); + private readonly CancellationTokenSource _stoppingSource = new CancellationTokenSource(); + private readonly CancellationTokenSource _stoppedSource = new CancellationTokenSource(); + private readonly ILogger _logger; + + public ApplicationLifetime(ILogger logger) + { + _logger = logger; + } + + /// + /// Triggered when the application host has fully started and is about to wait + /// for a graceful shutdown. + /// + public CancellationToken ApplicationStarted => _startedSource.Token; + + /// + /// Triggered when the application host is performing a graceful shutdown. + /// Request may still be in flight. Shutdown will block until this event completes. + /// + public CancellationToken ApplicationStopping => _stoppingSource.Token; + + /// + /// Triggered when the application host is performing a graceful shutdown. + /// All requests should be complete at this point. Shutdown will block + /// until this event completes. + /// + public CancellationToken ApplicationStopped => _stoppedSource.Token; + + /// + /// Signals the ApplicationStopping event and blocks until it completes. + /// + public void StopApplication() + { + // Lock on CTS to synchronize multiple calls to StopApplication. This guarantees that the first call + // to StopApplication and its callbacks run to completion before subsequent calls to StopApplication, + // which will no-op since the first call already requested cancellation, get a chance to execute. + lock (_stoppingSource) + { + ExecuteHandlers(_stoppingSource); + } + } + + /// + /// Signals the ApplicationStarted event and blocks until it completes. + /// + public void NotifyStarted() + { + ExecuteHandlers(_startedSource); + } + + /// + /// Signals the ApplicationStopped event and blocks until it completes. + /// + public void NotifyStopped() + { + ExecuteHandlers(_stoppedSource); + } + + private static void ExecuteHandlers(CancellationTokenSource cancel) + { + // Noop if this is already cancelled + if (cancel.IsCancellationRequested) + { + return; + } + + // Run the cancellation token callbacks + cancel.Cancel(throwOnFirstException: false); + } +} diff --git a/src/ThingsGateway.Admin.NetCore/Services/AuthService.cs b/src/ThingsGateway.Admin.NetCore/Services/AuthService.cs index ca2c99103..40f92145f 100644 --- a/src/ThingsGateway.Admin.NetCore/Services/AuthService.cs +++ b/src/ThingsGateway.Admin.NetCore/Services/AuthService.cs @@ -136,7 +136,6 @@ public class AuthService : IAuthService /// 登录策略 /// 用户登录参数 /// 用户信息 - /// cookie方式登录 /// 登录输出结果 private async Task ExecLogin(LoginPolicy loginPolicy, LoginInput input, SysUser sysUser) { diff --git a/src/ThingsGateway.Photino/Program.cs b/src/ThingsGateway.Photino/Program.cs index e32bc6d02..5881ff75b 100644 --- a/src/ThingsGateway.Photino/Program.cs +++ b/src/ThingsGateway.Photino/Program.cs @@ -17,12 +17,12 @@ using System.Text; using System.Text.Encodings.Web; using System.Text.Unicode; +using ThingsGateway.Admin.NetCore; + namespace ThingsGateway.Photino; internal class Program { - internal static CancellationTokenSource CancellationTokenSource = new(); - internal static CancellationToken CancellationToken = CancellationTokenSource.Token; [STAThread] private static void Main(string[] args) @@ -69,11 +69,36 @@ internal class Program AppDomain.CurrentDomain.UnhandledException += (sender, error) => { }; + + + StartHostedService(app.Services); app.Run(); - CancellationTokenSource.Cancel(); - CancellationTokenSource.Dispose(); - var _hostedServiceExecutor = app.Services.GetRequiredService(); - _hostedServiceExecutor.StopAsync(default).ConfigureAwait(false).GetAwaiter().GetResult(); + StopHostedService(app.Services); } + + public static void StartHostedService(IServiceProvider serviceProvider) + { + + var applicationLifetime = serviceProvider.GetRequiredService(); + var hostedServiceExecutor = serviceProvider.GetRequiredService(); + // Fire IHostedService.Start + hostedServiceExecutor.StartAsync(default).ConfigureAwait(false).GetAwaiter().GetResult(); + + applicationLifetime.NotifyStarted(); + + } + + public static void StopHostedService(IServiceProvider serviceProvider) + { + + var applicationLifetime = serviceProvider.GetRequiredService(); + applicationLifetime.StopApplication(); + + var _hostedServiceExecutor = serviceProvider.GetRequiredService(); + _hostedServiceExecutor.StopAsync(default).ConfigureAwait(false).GetAwaiter().GetResult(); + applicationLifetime.NotifyStopped(); + + } + } diff --git a/src/ThingsGateway.Photino/Startup.cs b/src/ThingsGateway.Photino/Startup.cs index cf4120c26..7880b0fc6 100644 --- a/src/ThingsGateway.Photino/Startup.cs +++ b/src/ThingsGateway.Photino/Startup.cs @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Localization; using ThingsGateway.Admin.Application; @@ -59,6 +60,10 @@ public class Startup : AppStartup private void ConfigureAdminApp(IServiceCollection services) { + services.AddSingleton(); + services.AddSingleton(); + + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -82,13 +87,6 @@ public class Startup : AppStartup } - public void UseAdminCore(IServiceProvider serviceProvider) - { - var _hostedServiceExecutor = serviceProvider.GetRequiredService(); - // Fire IHostedService.Start - _hostedServiceExecutor.StartAsync(Program.CancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(); - - } } diff --git a/src/Version.props b/src/Version.props index 0fd2a5382..b98f9cab5 100644 --- a/src/Version.props +++ b/src/Version.props @@ -1,6 +1,6 @@ - 6.0.5.1 + 6.0.5.2 diff --git a/src/tools/ThingsGateway.Razor/Components/FAIconList.razor.cs b/src/tools/ThingsGateway.Razor/Components/FAIconList.razor.cs index 692bd9672..c08405cc7 100644 --- a/src/tools/ThingsGateway.Razor/Components/FAIconList.razor.cs +++ b/src/tools/ThingsGateway.Razor/Components/FAIconList.razor.cs @@ -15,7 +15,7 @@ namespace ThingsGateway.Razor; /// /// FAIconList 组件 /// -[JSModuleAutoLoader("Components/ThemeToggle.razor.js", JSObjectReference = true)] +[JSModuleAutoLoader("Components/FAIconList.razor.js", JSObjectReference = true)] public partial class FAIconList : IAsyncDisposable { private string? ClassString => CssBuilder.Default("icon-list")