Skip to content

Commit 273dbb9

Browse files
authored
Host: fix Cancellation not aborting Start in some cases (#113442)
1 parent dfd3cc0 commit 273dbb9

File tree

2 files changed

+32
-0
lines changed
  • src/libraries/Microsoft.Extensions.Hosting

2 files changed

+32
-0
lines changed

src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,10 @@ private static async Task ForeachService<T>(
338338
{
339339
exceptions.AddRange(task.Exception.InnerExceptions); // Log exception from async method.
340340
}
341+
else if (task.IsCanceled)
342+
{
343+
exceptions.Add(new TaskCanceledException(task));
344+
}
341345
}
342346
else
343347
{

src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Internal/HostTests.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,6 +1453,23 @@ public async Task HostedServiceFactoryExceptionGetsLogged()
14531453
Assert.Equal("HostedServiceStartupFaulted", events[0].EventId.Name);
14541454
}
14551455

1456+
[Fact]
1457+
public async Task HostConcurrentCancelledStartAsyncAbortsStart()
1458+
{
1459+
using CancellationTokenSource cancellationTokenSource = new();
1460+
StartAsyncCancelledService service = new(cancellationTokenSource);
1461+
1462+
using IHost host = CreateBuilder()
1463+
.ConfigureServices((hostContext, services) =>
1464+
{
1465+
services.Configure<HostOptions>(o => o.ServicesStartConcurrently = true);
1466+
services.AddHostedService(sp => service);
1467+
})
1468+
.Build();
1469+
1470+
await Assert.ThrowsAsync<TaskCanceledException>(() => host.StartAsync(cancellationTokenSource.Token));
1471+
}
1472+
14561473
/// <summary>
14571474
/// Tests that when a BackgroundService is canceled when stopping the host,
14581475
/// no error is logged.
@@ -1698,6 +1715,17 @@ private class BackgroundServiceDoesNotCallBase : BackgroundService
16981715
public override Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
16991716
}
17001717

1718+
private class StartAsyncCancelledService(CancellationTokenSource cancellationTokenSource) : IHostedService
1719+
{
1720+
public Task StartAsync(CancellationToken cancellationToken)
1721+
{
1722+
cancellationTokenSource.Cancel();
1723+
return Task.FromCanceled(cancellationToken);
1724+
}
1725+
1726+
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
1727+
}
1728+
17011729
private class SlowStartService : IHostedService
17021730
{
17031731
public async Task StartAsync(CancellationToken cancellationToken)

0 commit comments

Comments
 (0)