title: How to gracefully capture exceptions from timer events?
body: <p>In an ASP Net Core 2 MVC app, I am using <a href="https://blogs.msdn.microsoft.com/cesardelatorre/2017/11/18/implementing-background-tasks-in-microservices-with-ihostedservice-and-the-backgroundservice-class-net-core-2-x/" rel="nofollow noreferrer">this</a> <code>BackGroundService</code> (via <code>IHostingService</code>) with the below implementation to update singleton gauge objects for a real-time dashboard. However, I don't know of a good way to ensure I capture any exceptions thrown when the <code>Update</code> event is fired.</p>
  
  <p>Note: I am aware of <code>AppDomain.UnhandledException</code> but find it to be more of a sledgehammer approach and would like something easier to maintain and scale. </p>
  
  <p>Or, is there an entirely better way to periodically update data in a background task in <code>ASP.NET Core 2</code>?</p>
  
  <pre><code>public class GaugeUpdater : BackgroundService
  {
      private readonly List&lt;IUpdateable&gt; _updatables;
  
      private Timer _timer;
  
      public GaugeUpdater (IEnumerable&lt;IUpdateable&gt; updateables)
      {
          _updatables = updateables.ToList();
      }
  
      protected override async Task ExecuteAsync(CancellationToken stoppingToken)
      {
          if (!stoppingToken.IsCancellationRequested)
          {
              await InitializeUpdateables();
  
              SetTimer();
          }
      }
  
      private void SetTimer()
      {
          const int intervalMilliseconds = 60_000;
  
          var interval = new TimeSpan(0, 0, 0, 0, intervalMilliseconds);
          _timer = new Timer(UpdateAll, null, interval, interval);
      }
  
      private async Task InitializeUpdateables()
      {
          var tasks = _updatables.Select(x =&gt; x.Initialize()).ToList();
  
          await Task.WhenAll(tasks);
      }
  
      private async void UpdateAll(object state)
      {
          // TODO: Find way to handle exceptions, as awaiting async void makes it impossible for caller to catch.
          // AppDomain.UnhandledException is possible but hard to maintain and handle in this scope.
          _updatables.ForEach(async x =&gt; await x.Update());
      }
  }
  </code></pre>