ServiceBaseLifetimeHost
parent
32774f3d7c
commit
e62787c5f8
|
@ -1,8 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace NDB.Hosting.WindowsService
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
using System.ServiceProcess;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NDB.Hosting.WindowsService
|
||||
{
|
||||
public class ServiceBaseLifetime : ServiceBase, IHostLifetime
|
||||
{
|
||||
private readonly TaskCompletionSource<object> _delayStart = new TaskCompletionSource<object>();
|
||||
|
||||
public ServiceBaseLifetime(IApplicationLifetime applicationLifetime)
|
||||
{
|
||||
ApplicationLifetime = applicationLifetime ?? throw new ArgumentNullException(nameof(applicationLifetime));
|
||||
}
|
||||
|
||||
private IApplicationLifetime ApplicationLifetime { get; }
|
||||
|
||||
public Task WaitForStartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(() => _delayStart.TrySetCanceled());
|
||||
ApplicationLifetime.ApplicationStopping.Register(Stop);
|
||||
|
||||
new Thread(Run).Start(); // Otherwise this would block and prevent IHost.StartAsync from finishing.
|
||||
return _delayStart.Task;
|
||||
}
|
||||
|
||||
private void Run()
|
||||
{
|
||||
try
|
||||
{
|
||||
Run(this); // This blocks until the service is stopped.
|
||||
_delayStart.TrySetException(new InvalidOperationException("Stopped without starting"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_delayStart.TrySetException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Stop();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
// Called by base.Run when the service is ready to start.
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
_delayStart.TrySetResult(null);
|
||||
base.OnStart(args);
|
||||
}
|
||||
|
||||
// Called by base.Stop. This may be called multiple times by service Stop, ApplicationStopping, and StopAsync.
|
||||
// That's OK because StopApplication uses a CancellationTokenSource and prevents any recursion.
|
||||
protected override void OnStop()
|
||||
{
|
||||
ApplicationLifetime.StopApplication();
|
||||
base.OnStop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NDB.Hosting.WindowsService
|
||||
{
|
||||
public static class ServiceBaseLifetimeHostExtensions
|
||||
{
|
||||
public static IHostBuilder UseServiceBaseLifetime(this IHostBuilder hostBuilder)
|
||||
{
|
||||
return hostBuilder.ConfigureServices((hostContext, services) => services.AddSingleton<IHostLifetime, ServiceBaseLifetime>());
|
||||
}
|
||||
|
||||
public static Task RunAsServiceAsync(this IHostBuilder hostBuilder, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return hostBuilder.UseServiceBaseLifetime().Build().RunAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue