title: aspnet core stop background running task
body: <p>I have an api method which runs in background (async) for ~6 mins.
  I want to allow the user to cancel it from another api request.</p>
  
  <p>For Ex.</p>
  
  <p><code>/api/credits/post/25</code> will start the background task and returns OK response immediately.</p>
  
  <p><code>/api/credits/stop/25</code> will stop running background task.</p>
  
  <p>my current code.</p>
  
  <p>API</p>
  
  <pre><code>[Route("api/[controller]")]
  public class CreditController : Controller
  {
      private readonly CreditService _creditService;
      public CreditController (CreditService creditService)
      {
          _creditService = creditService;
      }
  
      [HttpPost("[action]")]
      public string Post(int id)
      {
          if (_creditService.Instances.Any(p =&gt; p.ID == id))
              return "already running " + id;
          _creditService.Post(id, (s,e) =&gt;
          {
              // sending realtime changes to user using SignalR.
              // so that they will see progress and whats running in background 
          });
          return "started " + id;
      }
  
      [HttpPost("[action]")]
      public string Stop(int id)
      {
          var instance = _creditService.Instances.SingleOrDefault(p =&gt; p.ID == id));
          if (instance == null)
              return id + " is not running";
          instance.CancelToken.Cancel();
          return id + " stoppped";            
      }
  }
  </code></pre>
  
  <p>Service</p>
  
  <pre><code>public class CreditService
  {
      public static List&lt;CreditService&gt; Instances = new List&lt;CreditService&gt;();
  
      public Status&lt;object&gt; Status = new Status&lt;object&gt;();
      public CancellationTokenSource CancelToken = new CancellationTokenSource();
  
      public Task Post(int id, PropertyChangedEventHandler handler = null)
      {
          Instances.Add(this);
          if (handler != null) Status.PropertyChanged += handler;
  
          return Task.Factory.StartNew(() =&gt;
          {
              try
              {
                  // long running task
              }
              catch (Exception e)
              {
                  Status.Error = e.Message ?? e.ToString();
              }
              finally
              {
                  if (handler != null) Status.PropertyChanged -= handler;
                  Status.Clear();
                  CancelToken.Dispose();
                  Instances.Remove(this);
              }
          });
      }
  }
  </code></pre>
  
  <p>This is working as expected. but i want to know is this a good approach or is there any other better alternative to this.</p>
  
  <p>Also this will not work if i use load balancer and multiple instances of application. How do i fix this.</p>