Try these two lines in startup.cs:
services.AddSingleton<TimedHealthCheckService>();
services.AddHostedService<TimedHealthCheckService>(provider => provider.GetService<TimedHealthCheckService>());
The first line above tells the service provider to create a singleton and give it to anyone who wants a TimedHealthCheckService, like your controller's constructor. However, the service provider is unaware that the singleton is actually an IHostedService and that you want it to call StartAsync().
The second line tells the service provider that you want to add a hosted service, so it'll call StartAsync() when the application starts running. AddHostedService accepts a Func<IServiceProvider,THostedService> callback. The callback we provide fetches the singleton TimedHealthCheckService from the service provider and returns it back to the service provider as an IHostedService. The service provider then calls its StartAsync() function.
And in your controller:
public HealthCheckController(ILogger<HealthCheckController> logger, TimedHealthCheckService hostedService)