title: asp.NET Core timed BackgroundService cannot be stopped in Controller with StopAsync()
body: <p>I have implemented a REST API Server with asp.NET Core. I need a background task which does some administrative stuff.</p>
  
  <p>I tried the several suggestions in the web to create a timed background task and implemented it as fpllowing:
  BackgroundService.cs</p>
  
  <pre><code>public abstract class BackgroundService : IHostedService, IDisposable
  {
      private Task _executingTask;
      private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();
  
      protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
  
      public virtual Task StartAsync(CancellationToken cancellationToken)
      {
          _executingTask = ExecuteAsync(_stoppingCts.Token);
  
          if (_executingTask.IsCompleted)
          {
              return _executingTask;
          }
  
          return Task.CompletedTask;
      }
  
      public virtual async Task StopAsync(CancellationToken cancellationToken)
      {
          if (_executingTask == null)
          {
              return;
          }
  
          try
          {
              _stoppingCts.Cancel();
          }
          finally
          {
              await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
          }
  
      }
  
      public virtual void Dispose()
      {
          _stoppingCts.Cancel();
      }
  }
  </code></pre>
  
  <p>RecureHostedService.cs</p>
  
  <pre><code>public class RecureHostedService : BackgroundService
  {
      private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
      private int _executionCount = 0;
      private Timer _timer;
  
      protected async override Task ExecuteAsync(CancellationToken stoppingToken)
      {
          while (!stoppingToken.IsCancellationRequested)
          {
              var count = Interlocked.Increment(ref _executionCount);
  
              log.InfoFormat(
                  "Timed Hosted Service is working. Count: {0}", count);
              await Task.Delay(10000, stoppingToken);
          }
      }
  }
  </code></pre>
  
  <p>SystemController.cs</p>
  
  <pre><code>public class SystemController : Controller
  {
      private readonly RecureHostedService _recureHostedService;
  
      public SystemController(IHostedService hostedService)
      {
          _recureHostedService = hostedService as RecureHostedService;
      }
      [HttpGet(ApiRoutes.System.Start)]
      public IActionResult Start()
      {
          Console.WriteLine("Start Service");
          _recureHostedService.StartAsync(new CancellationToken());
          return Ok();
      }
  
      [HttpGet(ApiRoutes.System.Stop)]
      public IActionResult Stop()
      {
          Console.WriteLine("Stop Service");
          Console.WriteLine(_recureHostedService == null);
          _recureHostedService.StopAsync(new CancellationToken());
          return Ok();
      }
  }
  </code></pre>
  
  <p>in Startup.cs I added the Service as Singleton:</p>
  
  <pre><code>services.AddSingleton&lt;IHostedService,RecureHostedService&gt;();
  </code></pre>
  
  <p>The RecureHostedService starts on startup of my app and does its work. When I do an APIrequest /api/v1/stop from the SystemController (method Stop()) I got an NullReferenceException in </p>
  
  <pre><code>_recureHostedService.StopAsync(new CancellationToken());
  </code></pre>
  
  <p>I found out that the private member variable _recureHostedService is null even if I had assigned it in the Constructor of the SystemController. So it seems that the Service Injection of _recureHostedService is not working. So the line </p>
  
  <pre><code>_recureHostedService = hostedService as RecureHostedService;
  </code></pre>
  
  <p>in the Constructor of SystemController assigns null to _recureHostedService. 
  How can that be? I've a lot of other Services injected to other Controllers and all works fine.
  Any idea from anyone, why it is not working with that Hosted Service?</p>
  
  <p>Best 
  Mic</p>