Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Implementations of IHostedService

I'm trying to create background services using IHostedService. Everything works fine if I only have ONE background service. When I try to create more than one implementation of IHostedService only the one that was registered first actually runs.

services.AddSingleton<IHostedService, HostedServiceOne>();
services.AddSingleton<IHostedService, HostedServiceTwo>();

In the above sample StartAsync on HostedServiceOne gets called but StartAsync on HostedServiceTwo never gets called. If I swap the order of registering the two implementations of IHostedService (put IHostedServiceTwo before IHostedServiceOne) then StartAsync on HostedServiceTwo gets called but never for HostedServiceOne.

EDIT:

I was directed to the following:

How to register multiple implementations of the same interface in Asp.Net Core?

However this isn't for IHostedService. To use the suggested approach I would have to make a call to serviceProvider.GetServices<IService>(); but it seems that IHostedService.StartAsync seems to be called internally. I'm not even sure where I would call that to trigger IHostedService.StartAsync.

like image 911
James Avatar asked Oct 09 '18 02:10

James


2 Answers

I had the same problem. It was necessary to return Task.CompletedTask in each services;

public class MyHostedService: IHostedService
{
    public Task StartAsync(CancellationToken cancellationToken)
    {
        Task.Run(() => SomeInfinityProcess(cancellationToken));
        return Task.CompletedTask;
    }

    public void SomeInfinityProcess(CancellationToken cancellationToken)
    {
        for (; ; )
        {
            Thread.Sleep(1000);
            if (cancellationToken.IsCancellationRequested)
                break;
        }
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

Startup.cs is same:

    services.AddHostedService<MyHostedService>();
    services.AddHostedService<MyHostedService2>();
    ...
like image 114
tlp Avatar answered Nov 09 '22 20:11

tlp


Register your HostedService as below :

// services.AddSingleton<IHostedService, HostedServiceOne>();
// services.AddSingleton<IHostedService, HostedServiceTwo>();

services.AddHostedService<HostedServiceOne>();
services.AddHostedService<HostedServiceTwo>();

[Update]:

See comments below by @nickvane :

It's because the first service registered is not returning a Task on the StartAsync method so the runtime is waiting and doesn't execute the StartAsync of the next registered hostedservice instance

It's likely the first StartAsync() didn't finish

like image 9
itminus Avatar answered Nov 09 '22 21:11

itminus