title: Is this the correct way to run scheduled async/await methods using System.Threading.Timer?
body: <p>I am currently working on a project where I would like to perform some periodic updates in the background and I would like to use async/await for that purpose using a System.Threading.Timer. I have not been able to find any articles on this particular subject.</p>
  
  <p>The following snippet works. I am just unsure about using a async method returning void when that should only be used for event handlers like button clicks. Is there anything that 'breaches' with best practice in the code below?</p>
  
  <pre><code>public class ScheduledCache
  {
      private CancellationTokenSource _cancelSource = new CancellationTokenSource();
      private Request _request = new Request();
      private Timer _timer;
  
      public void Start()
      {
          _cancelSource = new CancellationTokenSource();
          _timer = new Timer(UpdateAsync, null, 2000, Timeout.Infinite);
      }
  
      public void Stop()
      {
          _cancelSource.Cancel();
      }
  
      public async void UpdateAsync(object state)
      {
          try
          {
              await Task.WhenAll(UpdateSomethingAsync(_cancelSource.Token), UpdateSomethingElseAsync(_cancelSource.Token));
          }
          catch (OperationCanceledException)
          {
              // Handle cancellation
          }
          catch (Exception exception)
          {
              // Handle exception
          }
          finally
          {
              if (_cancelSource.IsCancellationRequested)
                  _timer = new Timer(UpdateAsync, null, 2000, Timeout.Infinite);
              else
                  _timer = new Timer(UpdateAsync, null, Timeout.Infinite, Timeout.Infinite);
          }
      }
  
      private async Task UpdateSomethingAsync(CancellationToken cancellationToken)
      {
          await Task.Run(new Action(_request.UpdateSomething));
      }
  
      private async Task UpdateSomethingElseAsync(CancellationToken cancellationToken)
      {
          await Task.Run(new Action(_request.UpdateSomethingElse));
      }
  }
  
  public class Request
  {
      public void UpdateSomething()
      {
          // Do some updates here
      }
  
      public void UpdateSomethingElse()
      {
          // Do some other updates here
      }
  }
  </code></pre>