title: Running multiple backend services using iHostedService
body: <p>Currently my web API is able to run on a schedule and trigger another end point in order to sync data. The services that needs to be called are stored in a yml file. I have managed to get it working for one service to run a schedule. What I want is to be able to save multiple endpoints with schedules of their own and for them to be scheduled and executed at the right time. </p>
  
  <p>Here is the code that I have now</p>
  
  <p>I have done this using iHostedService interface. </p>
  
  <p>This is the HostService class that implements iHostedService</p>
  
  <pre><code>public abstract class HostedService : IHostedService
  {
      private Task _executingTask;
      private CancellationTokenSource _cts;
  
      public Task StartAsync(CancellationToken cancellationToken)
      {
          _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
  
          _executingTask = ExecuteAsync(_cts.Token);
  
          // If the task is completed then return it, otherwise it's running
          return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
      }
  
      public async Task StopAsync(CancellationToken cancellationToken)
      {
          // Stop called without start
          if (_executingTask == null)
          {
              return;
          }
  
          // Signal cancel
          _cts.Cancel();
  
          // Wait until the task completes or the stop token triggers
          await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));
  
          cancellationToken.ThrowIfCancellationRequested();
      }
  
      // cancel
      protected abstract Task ExecuteAsync(CancellationToken cancellationToken);
  }
  </code></pre>
  
  <p>I am then extending this class and implementing what needs to be done in the <code>ExecuteAsync</code> as follows </p>
  
  <pre><code>public class DataRefreshService : HostedService
  {
      private readonly DataFetchService _dataFetchService;
  
      public DataRefreshService(DataFetchService randomStringProvider)
      {
          _dataFetchService = randomStringProvider;
      }
  
      protected override async Task ExecuteAsync(CancellationToken cancellationToken)
      {
          try
          {
              while (!cancellationToken.IsCancellationRequested)
              {
                  await _dataFetchService.UpdateData(cancellationToken);
  
                  TimeSpan span = _dataFetchService.GetNextTrigger();
  
                  await Task.Delay(span, cancellationToken);
              }
          } catch (Exception)
          {
              await StopAsync(cancellationToken);
              throw new Exception("Error trigger Sync service");
          }
      }
  }
  </code></pre>
  
  <p>This is what I have added to the Startup.cs file </p>
  
  <pre><code>services.AddSingleton&lt;DataFetchService&gt;();
  services.AddSingleton&lt;IHostedService, DataRefreshService&gt;();
  </code></pre>