Make IHealthCheckService work in ST-sync-context

\n\nCommit migrated from 2b673c89c2
This commit is contained in:
Ryan Nowak 2019-02-17 16:29:24 -08:00
parent ffc4b00764
commit 2849483895
3 changed files with 40 additions and 5 deletions

View File

@ -54,7 +54,7 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
{
foreach (var registration in registrations)
{
tasks[index++] = RunCheckAsync(scope, registration, cancellationToken);
tasks[index++] = Task.Run(() => RunCheckAsync(scope, registration, cancellationToken), cancellationToken);
}
await Task.WhenAll(tasks).ConfigureAwait(false);
@ -75,8 +75,6 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
private async Task<HealthReportEntry> RunCheckAsync(IServiceScope scope, HealthCheckRegistration registration, CancellationToken cancellationToken)
{
await Task.Yield();
cancellationToken.ThrowIfCancellationRequested();
var healthCheck = registration.Factory(scope.ServiceProvider);
@ -104,7 +102,7 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
checkCancellationToken = timeoutCancellationTokenSource.Token;
}
result = await healthCheck.CheckHealthAsync(context, checkCancellationToken);
result = await healthCheck.CheckHealthAsync(context, checkCancellationToken).ConfigureAwait(false);
var duration = stopwatch.GetElapsedTime();
@ -118,7 +116,6 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
Log.HealthCheckEnd(_logger, registration, entry, duration);
Log.HealthCheckData(_logger, registration, entry);
}
catch (OperationCanceledException ex) when (!cancellationToken.IsCancellationRequested)
{
var duration = stopwatch.GetElapsedTime();

View File

@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing;
using Microsoft.Extensions.Options;
@ -450,6 +451,39 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
});
}
[Fact]
public void CheckHealthAsync_WorksInSingleThreadedSyncContext()
{
// Arrange
var service = CreateHealthChecksService(b =>
{
b.AddAsyncCheck("test", async () =>
{
await Task.Delay(1).ConfigureAwait(false);
return HealthCheckResult.Healthy();
});
});
var hangs = true;
// Act
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3)))
{
var token = cts.Token;
token.Register(() => throw new OperationCanceledException(token));
SingleThreadedSynchronizationContext.Run(() =>
{
// Act
service.CheckHealthAsync(token).GetAwaiter().GetResult();
hangs = false;
});
}
// Assert
Assert.False(hangs);
}
private static DefaultHealthCheckService CreateHealthChecksService(Action<IHealthChecksBuilder> configure)
{
var services = new ServiceCollection();

View File

@ -12,4 +12,8 @@
<Reference Include="Microsoft.Extensions.Logging.Testing" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\..\Shared\test\SingleThreadedSynchronizationContext.cs" Link="Shared\SingleThreadedSynchronizationContext.cs"/>
</ItemGroup>
</Project>