Created
February 4, 2019 17:37
-
-
Save guitarrapc/7b7447a6df7843fc45a3b47a6b950cc2 to your computer and use it in GitHub Desktop.
Generic host + Windows Service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Extensions.Hosting; | |
using System; | |
using System.ServiceProcess; | |
using System.Threading; | |
using System.Threading.Tasks; | |
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(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment