diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/HostedServiceExecutor.cs b/src/Microsoft.AspNetCore.Hosting/Internal/HostedServiceExecutor.cs index 2237edd221..ee6fbcfad8 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/HostedServiceExecutor.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/HostedServiceExecutor.cs @@ -3,6 +3,8 @@ using System; using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -19,11 +21,11 @@ namespace Microsoft.AspNetCore.Hosting.Internal _services = services; } - public void Start() + public async Task StartAsync(CancellationToken token) { try { - Execute(service => service.Start()); + await ExecuteAsync(service => service.StartAsync(token)); } catch (Exception ex) { @@ -31,11 +33,11 @@ namespace Microsoft.AspNetCore.Hosting.Internal } } - public void Stop() + public async Task StopAsync(CancellationToken token) { try { - Execute(service => service.Stop()); + await ExecuteAsync(service => service.StopAsync(token)); } catch (Exception ex) { @@ -43,7 +45,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal } } - private void Execute(Action callback) + private async Task ExecuteAsync(Func callback) { List exceptions = null; @@ -51,7 +53,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal { try { - callback(service); + await callback(service); } catch (Exception ex) { diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs b/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs index 3c5423830f..d4e7c09cd6 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs @@ -123,7 +123,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal _applicationLifetime?.NotifyStarted(); // Fire IHostedService.Start - _hostedServiceExecutor.Start(); + await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false); _logger.Started(); @@ -296,7 +296,10 @@ namespace Microsoft.AspNetCore.Hosting.Internal } // Fire the IHostedService.Stop - _hostedServiceExecutor?.Stop(); + if (_hostedServiceExecutor != null) + { + await _hostedServiceExecutor.StopAsync(cancellationToken).ConfigureAwait(false); + } // Fire IApplicationLifetime.Stopped _applicationLifetime?.NotifyStopped(); diff --git a/src/Microsoft.Extensions.Hosting.Abstractions/IHostedService.cs b/src/Microsoft.Extensions.Hosting.Abstractions/IHostedService.cs index 75abac9ef2..4fb372ca2b 100644 --- a/src/Microsoft.Extensions.Hosting.Abstractions/IHostedService.cs +++ b/src/Microsoft.Extensions.Hosting.Abstractions/IHostedService.cs @@ -1,6 +1,9 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Threading; +using System.Threading.Tasks; + namespace Microsoft.Extensions.Hosting { /// @@ -11,11 +14,11 @@ namespace Microsoft.Extensions.Hosting /// /// Triggered when the application host is ready to start the service. /// - void Start(); + Task StartAsync(CancellationToken cancellationToken); /// /// Triggered when the application host is performing a graceful shutdown. /// - void Stop(); + Task StopAsync(CancellationToken cancellationToken); } } diff --git a/test/Microsoft.AspNetCore.Hosting.Tests/WebHostTests.cs b/test/Microsoft.AspNetCore.Hosting.Tests/WebHostTests.cs index 298f2d85a5..ae3316fecd 100644 --- a/test/Microsoft.AspNetCore.Hosting.Tests/WebHostTests.cs +++ b/test/Microsoft.AspNetCore.Hosting.Tests/WebHostTests.cs @@ -999,14 +999,16 @@ namespace Microsoft.AspNetCore.Hosting public bool StopCalled { get; set; } public bool DisposeCalled { get; set; } - public void Start() + public Task StartAsync(CancellationToken token) { StartCalled = true; + return Task.CompletedTask; } - public void Stop() + public Task StopAsync(CancellationToken token) { StopCalled = true; + return Task.CompletedTask; } public void Dispose() @@ -1028,9 +1030,16 @@ namespace Microsoft.AspNetCore.Hosting _disposing = disposing; } - public void Start() => _started(); - - public void Stop() => _stopping(); + public Task StartAsync(CancellationToken token) + { + _started(); + return Task.CompletedTask; + } + public Task StopAsync(CancellationToken token) + { + _stopping(); + return Task.CompletedTask; + } public void Dispose() => _disposing(); }