title: TaskScheduler.UnobservedTaskException never gets called
body: <p>Based on my research, I have learned the following:</p>
  
  <ol>
  <li><code>TaskScheduler.UnobservedTaskException</code> must wait for the task to be garbage collected before that task's unobserved exception will bubble up to the <code>UnobservedTaskException</code> event.</li>
  <li>If you're using <code>Task.Wait()</code>, it'll never get called anyway, because you're blocking on an impending result from the Task, hence the exception will be thrown on <code>Task.Wait()</code> rather than bubble up to the <code>UnobservedException</code> event.</li>
  <li>Calling <code>GC.Collect()</code> manually is generally a bad idea unless you know exactly what you're doing, hence it's good in this case for confirming things, but not as a proper solution to the issue.</li>
  </ol>
  
  <p><strong>The Problem</strong></p>
  
  <p>If my application exits before the garbage collector kicks in, I absolutely 100% cannot get my <code>UnobservedTaskException</code> event to fire.</p>
  
  <p>Note the following code:</p>
  
  <pre><code>class Program
  {
      static void Main(string[] args)
      {
          TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
  
          Task.Factory.StartNew(() =&gt;
          {
              Console.WriteLine("Task started.");
              throw new Exception("Test Exception");
          });
  
          Thread.Sleep(1000);
          //GC.Collect();
          //GC.WaitForPendingFinalizers();
      }
  
      static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
      {
          File.WriteAllText(@"C:\data\TestException.txt", e.Exception.ToString());
          Console.WriteLine("UNOBSERVED EXCEPTION");
      }
  }
  </code></pre>
  
  <p>No exception file is written and nothing is written to the console. 10-15 minutes and more can go by after the application exits and still I see no evidence that my application's remains were garbage collected. You might ask, well why not just collect on exit? Well, my real world scenario is that <strong>my exception trapping runs inside a WCF service hosted inside a Windows service. I cannot trap when the Windows service is shutting down (and hence manually call <code>GC.Collect()</code>) because there is no event for that as far as I can see.</strong></p>
  
  <p>Where am I going wrong? How do I ensure that if something deep inside the WCF service is going to ultimately break my windows service, that I have a chance to log the exception before the service falls over?</p>