| File: HostTerminatorService.cs | Web Access |
| Project: src\src\Libraries\Microsoft.Extensions.Hosting.Testing\Microsoft.Extensions.Hosting.Testing.csproj (Microsoft.Extensions.Hosting.Testing) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace Microsoft.Extensions.Hosting.Testing; /// <summary> /// Terminates its host after a timeout set in <see cref="FakeHostOptions.TimeToLive"/>. /// </summary> internal sealed partial class HostTerminatorService : BackgroundService { internal bool DebuggerAttached = Debugger.IsAttached; internal TimeProvider TimeProvider = TimeProvider.System; private readonly IHost _host; private readonly FakeHostOptions _options; private readonly ILogger _logger; /// <summary> /// Initializes a new instance of the <see cref="HostTerminatorService"/> class. /// </summary> /// <param name="host">The <see cref="IHost"/> instance.</param> /// <param name="options">Options containing the time to live.</param> /// <param name="logger">An <see cref="ILogger"/> instance.</param> public HostTerminatorService(IHost host, FakeHostOptions options, ILogger<HostTerminatorService> logger) { _host = host; _options = options; _logger = logger; } /// <summary> /// Waits till the time to live is up or till the service is stopped. /// </summary> /// <param name="stoppingToken">Triggered when <see cref="IHostedService.StopAsync(CancellationToken)"/> is called.</param> /// <returns>A <see cref="Task"/> that represents the long running operations.</returns> protected override async Task ExecuteAsync(CancellationToken stoppingToken) { if (DebuggerAttached) { LogDebuggerAttached(); return; } await TimeProvider.Delay(_options.TimeToLive, stoppingToken).ConfigureAwait(false); using var timeoutTokenSource = TimeProvider.CreateCancellationTokenSource(_options.ShutDownTimeout); using var combinedTokenSource = CancellationTokenSource.CreateLinkedTokenSource( stoppingToken, timeoutTokenSource.Token); LogTimeToLiveUp(_options.TimeToLive); await _host.StopAsync(combinedTokenSource.Token).ConfigureAwait(false); _host.Dispose(); } [LoggerMessage(0, LogLevel.Warning, "FakeHostOptions.TimeToLive set to {TimeToLive} is up, disposing the host.")] private partial void LogTimeToLiveUp(TimeSpan timeToLive); [LoggerMessage(1, LogLevel.Information, "Debugger is attached. The host won't be automatically disposed.")] private partial void LogDebuggerAttached(); }