title: Code using async/await fails when an HttpClient request is sent
body: <p>I have a WinForms application that has two roles. If no command line parameters are present, the Main function calls Application.Run, and presents the UI. If command line parameters are present, Application.Run is NOT called. Instead, I call an async method like this:</p>
  
  <pre><code>result = HandleCommandLine(args).GetAwaiter().GetResult();
  </code></pre>
  
  <p>(I am new to async/await, and this form was based on a SO answer).</p>
  
  <p>The end goal is to loop through a list, and for each entry, start a new task. Each of those tasks should run in parallel with the others. The tasks are started like this:</p>
  
  <pre><code>runningTasks.Add(Task.Factory.StartNew((args) =&gt; HandlePlayback( (Dictionary&lt;string,string&gt;) ((object[])args)[0]), new object[] { runArgs } ));
  </code></pre>
  
  <p>The tasks are added to the collection of runningTasks, and I later call:</p>
  
  <pre><code>Task.WaitAll(runningTasks.ToArray());
  </code></pre>
  
  <p>In each of the runningTasks, I am trying to send web requests using HttpClient:</p>
  
  <pre><code>using (HttpResponseMessage response = await Client.SendAsync(message))
  {
      using (HttpContent responseContent = response.Content)
      {
          result = await responseContent.ReadAsStringAsync();
      }
  }
  </code></pre>
  
  <p>Once Client.SendAsync is called, the whole thing goes belly up. All of my runningTasks complete, and the application exits. Nothing past the Client.SendAsync executes in any of those tasks.</p>
  
  <p>Since I am new at async/await, I have very few ideas about what <em>exactly</em> might be wrong, and hence few ideas about how to fix it. I imagine it has something to do with the SynchronizationContexts in this situation (WinForms app acting like a console app), but I'm not grasping what I need to do and where to keep the service request and the web request async calls from causing everything to complete too early.</p>
  
  <p>I guess my question then is, why are (only some) 'awaited' calls causing all tasks to complete? What can I do about it?</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Two things. @Joe White: The WindowsFormsSynchronizationContext.Current is always null wherever I check.</p>
  
  <p>@David Pine: Minimal (kind of :) ) complete viable example follows. You will either need to add a command line argument to the project, or force execution to the HandleCommandLine function. In this example, it tries to make a website request for each of three sites. It doesn't appear to matter if they exist. The code reaches the Client.SendAsync some number of times (usually not three), but timing appears to matter. </p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Net;
  using System.Net.Http;
  using System.Text;
  using System.Threading.Tasks;
  using System.Windows.Forms;
  
  namespace WindowsFormsApplication1
  {
      static class Program
      {
          static List&lt;Task&gt; runningTasks = new List&lt;Task&gt;();
  
          [STAThread]
          static int Main()
          {
              int result = 1; // true, optimism
  
              Application.EnableVisualStyles();
              Application.SetCompatibleTextRenderingDefault(false);
  
              string[] args = Environment.GetCommandLineArgs();
  
              if (args.Length &gt; 1)
              {
                  // do the command line work async, while keeping this thread active
                  result = HandleCommandLine(args).GetAwaiter().GetResult();
              }
              else
              {
                  // normal interface mode
                  Application.Run(new Form1());
              }
  
              return result;
          }
  
  
          static async Task&lt;int&gt; HandleCommandLine(string[] args)
          {
              // headless mode
  
              int result = 1; // true, optimism
  
              result = await HandleControlMode(args);
  
  
              return result;
          }
  
          private static async Task&lt;int&gt; HandleControlMode(string[] Arguments)
          {
              int result = 1; // optimism
  
              try
              {
                  List&lt;string&gt; sites = new List&lt;string&gt;() { @"http://localhost/site1", @"http://localhost/site2", @"http://localhost/site3" };
                  foreach (string site in sites)
                  {
                      Begin(site);    // fire off tasks
  
                      // the HandleControlMode method is async because in other circumstances, I do the following:
                      //await Task.Delay(5000); // sleep 5 seconds
  
                  }
  
                  // wait while all test running threads complete
                  try
                  {
                      Task.WaitAll(runningTasks.ToArray());
                  }
                  catch (Exception)
                  {
                      // not really a catch all handler...
                  }
              }
              catch (Exception)
              {
                  // not really a catch all handler...
              }
  
              return result;
  
          }
  
          private static void Begin(string site)
          {
              //runningTasks.Add(Task.Factory.StartNew(() =&gt; HandlePlayback(runArgs)));
              runningTasks.Add(Task.Factory.StartNew((args) =&gt; HandlePlayback((string)((object[])args)[0]), new object[] { site }));
          }
  
          private static async Task&lt;int&gt; HandlePlayback(string site)
          {
              int result = 1;
  
              try
              {
                  PlaybackEngine engine = new PlaybackEngine(site);
                  bool runResult = await engine.RunCommandLine(site);
  
                  if (!runResult)
                  {
                      result = 0;
                  }
              }
              catch (Exception)
              {
                  result = 0;
              }
  
              return result;
          }
      }
  
      public class PlaybackEngine
      {
          private static HttpClientHandler ClientHandler = new HttpClientHandler()
          {
              AllowAutoRedirect = false,
              AutomaticDecompression = System.Net.DecompressionMethods.GZip | DecompressionMethods.Deflate
          };
          private static HttpClient Client = new HttpClient(ClientHandler);
  
          public string Target { get; set; }
  
          public PlaybackEngine(string target)
          {
              Target = target;
          }
  
          public async Task&lt;bool&gt; RunCommandLine(string site)
          {
              bool success = true;
              string response = await this.SendRequest();
              return success;
          }
  
          private async Task&lt;string&gt; SendRequest()
          {
              string result = string.Empty;
  
              string requestTarget = Target;
  
              HttpMethod method = HttpMethod.Post;
              var message = new HttpRequestMessage(method, requestTarget);
  
              StringContent requestContent = null;
              requestContent = new StringContent("dummycontent", Encoding.UTF8, "application/x-www-form-urlencoded");
  
              message.Content = requestContent;
  
              try
              {
                  using (HttpResponseMessage response = await Client.SendAsync(message))
                  {
                      using (HttpContent responseContent = response.Content)
                      {
                          result = await responseContent.ReadAsStringAsync();
                          System.Diagnostics.Debug.WriteLine(result);
                      }
                  }
  
              }
              catch (Exception ex)
              {
  
              }
  
              return result;
          }
      }
  }
  </code></pre>
  
  <p><strong>UPDATE2:</strong>
  I put similar code online at <a href="http://rextester.com/CJS33330" rel="nofollow noreferrer">http://rextester.com/CJS33330</a></p>
  
  <p>It's a straight console app, and I've added .ConfigureAwait(false) to all awaits (with no effect). In separate testing, I tried 4 or 5 other ways to call the first async function from Main - which all worked but had the same behavior.</p>