title: Task WhenAll combined with ContinueWith not work as expected
body: <p>I have a Winform project that inside of the winform class I have a property called DataBindingTasks like so.  </p>
  
  <pre><code>// create a task list to determine when tasks have finished during load
  protected List&lt;Task&gt; DataBindingTasks = new List&lt;Task&gt;();
  </code></pre>
  
  <p>I have several async void methods that I am calling in the winform "Load" event that are all similar to the following.  </p>
  
  <pre><code>private async void BindSomething(int millSecToWait)
  {
      var someTask = Task.Factory.StartNew(() =&gt;
      {
          // do some work
          System.Threading.Thread.Sleep(millSecToWait);
  
          // return some list for binding
          return new List&lt;int&gt;();
      });
      // add the task to the task list
      DataBindingTasks.Add(someTask);
  
      // wait until data has loaded
      var listToBind = await someTask;
  
      // bind the data to a grid
  }
  </code></pre>
  
  <p>I am calling the <code>BindSomething</code> methods on load.<br>
  I say methods because there are several of these binding types of methods that are called on load.  </p>
  
  <pre><code>private void Form_Load(object sender, EventArgs e)
  {
      // async bind something and let UI continue
      // fire and forget
      BindSomething(5000);
      BindSomething(8000);
      BindSomething(2000);
      BindSomething(2000);
  
      // code to execute when all data binding tasks have completed
      Task.WhenAll(DataBindingTasks).ContinueWith((x) =&gt;
      {
          // Do something after all async binding tasks have completed
      });
  }
  </code></pre>
  
  <p>EXCEPT the <code>ContinueWith</code> code is executing even though all the tasks have not completed.</p>
  
  <p>Here is a screen shot showing that all task are not complete. </p>
  
  <p><a href="https://i.stack.imgur.com/1dp3p.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1dp3p.png" alt="enter image description here"></a></p>
  
  <p><strong>UPDATED 10/29</strong><br>
  The problem is obviously deeper than the sample code above and the sample code above does not fully explain the true scenario.  </p>
  
  <p>I will try to explain in greater detail but try to not make it to long.  </p>
  
  <p>This is a Winform application.<br>
  We have created a base winform "BaseForm" that all other winforms will inherit from.<br>
  We have overridden the "OnLoad" event in the "BaseForm" so that we can call a new method that all inherited forms will have called "LoadData".<br>
  Since "LoadData" can have async method calls, the base form needs to know when the "LoadData" method is finished.<br>
  So in the base form was have some of the following: </p>
  
  <pre><code>protected List&lt;Task&gt; DataBindingTasks = new List&lt;Task&gt;();
  
  public event EventHandler DataBindingTasksComplete;
  protected void OnDataBindingTasksComplete(EventArgs e)
  {
      if (DataBindingTasksComplete != null)
      {
          DataBindingTasksComplete(this, e);
      }
      // now clear the list
      DataBindingTasks.Clear();
  }
  
  // NOTE: this is inside the OnLoad called before base.OnLoad(e)
  Task.WhenAll(DataBindingTasks).ContinueWith((x) =&gt;
  {
      OnDataBindingTasksComplete(EventArgs.Empty);
  });
  </code></pre>
  
  <p>The hope was that all inherited forms would add any of their "async" tasks to this list so that the base form could fire the "DataBindingTasksComplete" event so they would know that form has finished loading.  </p>
  
  <p>The problem "as perceived to us at the time of the issue" was that the "WhenAll().ContinueWith" was not waiting until all the tasks on the list had completed.<br>
  BUT as someone noted, the list might have changed.<br>
  So here is most likely what happened.<br>
  There are 4 "BindSomething" methods that are marked async all called from the Form_Load<br>
  The 2nd or so line down inside the "BindSomething" method is used to add a task to the "BaseForm.DataBindingTasks" list.<br>
  Since each of these calls are marked async, the Form_Load continues to call all 4 as a "fire and forget".<br>
  After that, it returns back to the BaseForm OnLoad which then looks at the "DataBindingTasks" list to see if all tasks have completed.<br>
  My best guess is that one of the "BindSomething" methods was in the middle of adding its task to the list yet the Base.OnLoad has already started looking at the list.  </p>
  
  <p>I could add 4 "fake" tasks (like thread sleep) to the list even before calling the "BindSomething" methods as "place holders" and then inside the "BindSomething" methods swap out the "fake" tasks with the "real" tasks.<br>
  This seams messy and most likely will cause other issues.<br>
  The most likely fix is to not use a task list / WhenAll.ContinueWith and instead call the load data with "await" and then raise the event on the next line.  </p>