title: Why does this Task return early? Have I done something wrong?
body: <p>I'm trying to set up a bunch of workers with some minimal coupling, but I'd like to use C# <code>async</code> and tasks. Not all of the tasks will be purely asynchronous (some will be completely synchronous). The motivation for doing this is that I want to create some simple methods that execute business logic, and chain them together using the <code>System.Threading.Tasks.Task</code> API to preserve some notion of ordering. Basically, I want to create a first task, register some continuations, and then wait for the final task to complete.</p>
  
  <p>Here's the simple prototype I built just to see if what I want to do even works: </p>
  
  <pre><code>void Main()
  {
      var worker = new Worker();
  
      var work = worker.StartWork(1, 2000);
      work.ConfigureAwait(false);
  
      var final = work.ContinueWith(_ =&gt; worker.StartWork(2, 0))
          .ContinueWith(ant =&gt; worker.StartWork(3, 1500));
  
      var awaiter = final.ContinueWith(_ =&gt; Tuple.Create(_.Id, _.Status));
      Console.WriteLine("\"final\" completed with result {0}", awaiter.Result);
      Console.WriteLine("Done.");
  }
  
  // Define other methods and classes here
  class Worker {
      internal async Task StartWork(int phase, int delay) {
          Console.WriteLine("Entering phase {0} (in Task {1}) with {2} milliseconds timeout.", phase, Task.CurrentId, delay);
          if (delay &gt; 0)
          {
              Console.WriteLine("Do wait for {0} milliseconds.", delay);
              await Task.Delay(delay);
          }
  
          Console.WriteLine("ending phase {0}", phase);
      }
  }
  </code></pre>
  
  <p>The problem seems to be in <del>awaiting</del> waiting on the so-called <code>awaiter</code> task:</p>
  
  <pre><code>Entering phase 1 (in Task ) with 2000 milliseconds timeout.
  Do wait for 2000 milliseconds.
  ending phase 1
  Entering phase 2 (in Task 769) with 0 milliseconds timeout.
  ending phase 2
  Entering phase 3 (in Task 770) with 1500 milliseconds timeout.
  Do wait for 1500 milliseconds.
  "final" completed with result (770, RanToCompletion)
  Done.
  ending phase 3
  </code></pre>
  
  <p>Is this just not supported? I thought I understood the <code>Task</code> API pretty well, but clearly I don't. I think that I can convert this to not use <code>async</code> or task, and just execute the method completely synchronously, but that seems like a bad method of doing things. The continuations that I want to run are not exactly this (they just accept a <code>CancellationToken</code>). There's no particular dependency on messages between tasks - I just need to preserve some notion of ordering.</p>
  
  <p>Thank you.</p>
  
  <p><strong>Edit:</strong> I incorrectly used the word <code>awaiting</code> above: I know that accessing <code>Task.Result</code> is completely synchronous. My apologies.</p>
  
  <p><strong>Edit 2:</strong> What I expected to occur was that calling <code>ContinueWith(_ =&gt; worker.Start(2, 0))</code> would return a task to <code>ContinueWith</code>, and the TPL would internally await the task returned by <code>worker.StartWork</code> when my user delegate returned a task. Looking at the overload list for <code>ContinueWith</code>, this was clearly incorrect. Part of what I'm trying to solve is how to wait from the <code>Main</code> method that schedules the work; I don't want to exit before all continuations have completed.</p>
  
  <p>The motivation I had for using <code>ContinueWith</code> was that I have requirements similar to the following:</p>
  
  <ol>
  <li>There are three phases to the main method.</li>
  <li>Phase 1 creates three workers: <code>a</code>, <code>b</code>, and <code>c</code>.</li>
  <li>Phase 2 starts an additional worker <code>d</code> upon the completion of tasks <code>b</code> and <code>c</code>, and another worker <code>e</code> upon completion of <code>a</code> and <code>b</code> (the dependency is that these tasks must be created in this order)</li>
  <li>A process similar to this follows until all the work is complete.</li>
  </ol>
  
  <p>If I understand the feedback in the comments correctly, I have essentially two ways I can do this:</p>
  
  <ol>
  <li>Make the methods synchronous, and register the continuations myself.</li>
  <li>Leave the methods marked as <code>async Task</code>, and use the <code>await</code> keyword along with the <code>Task.WhenAll</code> API to schedule the continuations.</li>
  </ol>