title: How to prevent an application from terminating before the completion of all fire-and-forget tasks?
body: <p>I have an application that regularly launches fire-and-forget tasks, mainly for logging purposes, and my problem is that when the application is closed, any currently running fire-and-forget tasks are aborted. I want to prevent this from happening, so I am searching for a mechanism that will allow me to <code>await</code> the completion of all running fire-and-forget operations before closing my app. I don't want to handle their possible exceptions, I don't care about these. I just want to give them the chance to complete (probably with a timeout, but this is not part of the question).</p>
  <p>You could argue that this requirement makes my tasks not truly fire-and-forget, and there is some truth in that, so I would like to clarify this point:</p>
  <ol>
  <li>The tasks are fire-and-forget locally, because the method that launches them is not interested about their outcome.</li>
  <li>The tasks are not fire-and-forget globally, because the application as a whole cares about them.</li>
  </ol>
  <p>Here is a minimal demonstration of the problem:</p>
  <pre><code>static class Program
  {
      static async Task Main(string[] args)
      {
          _ = Log(&quot;Starting&quot;); // fire and forget
          await Task.Delay(1000); // Simulate the main asynchronous workload
          CleanUp();
          _ = Log(&quot;Finished&quot;); // fire and forget
  
          // Here any pending fire and forget operations should be awaited somehow
      }
  
      private static void CleanUp()
      {
          _ = Log(&quot;CleanUp started&quot;); // fire and forget
          Thread.Sleep(200); // Simulate some synchronous operation
          _ = Log(&quot;CleanUp completed&quot;); // fire and forget
      }
  
      private static async Task Log(string message)
      {
          await Task.Delay(100); // Simulate an async I/O operation required for logging
          Console.WriteLine($&quot;{DateTime.Now:HH:mm:ss.fff} {message}&quot;);
      }
  }
  </code></pre>
  <p>Output:</p>
  <pre class="lang-xml prettyprint-override"><code>11:14:11.441 Starting
  11:14:12.484 CleanUp started
  Press any key to continue . . .
  </code></pre>
  <p>The <code>&quot;CleanUp completed&quot;</code> and <code>&quot;Finished&quot;</code> entries are not logged, because the application terminates prematurely, and the pending tasks are aborted. Is there any way that I can await them to complete before closing?</p>
  <p>Btw this question is inspired by a <a href="https://stackoverflow.com/questions/64712039/async-operation-in-c-sharp-not-working-as-expected-fire-and-forget-scenario">recent question</a> by @SHAFEESPS, that was sadly closed as unclear.</p>
  <p><strong>Clarification:</strong> The minimal example presented above contains a single type of fire-and-forget operation, the <code>Task Log</code> method. The fire-and-forget operations launched by the real world application are multiple and heterogeneous. Some even return generic tasks like <code>Task&lt;string&gt;</code> or <code>Task&lt;int&gt;</code>.</p>
  <p>It is also possible that a fire-and-forget task may fire secondary fire-and-forget tasks, and these should by allowed to start and be awaited too.</p>