title: NetworkStream ReadAsync and WriteAsync hang infinitelly when using CancellationTokenSource - Deadlock Caused by Task.Result (or Task.Wait)
body: <p>After reading pretty much every question on Stack Overflow and Microsoft's documentation about NetworkStream, I dont understand what is wrong with my code.</p>
  
  <p>The problem I see is that my method GetDataAsync() hangs very often.  I call this method from Init Method like so:</p>
  
  <pre><code>public MyView(string id)
  {
      InitializeComponent();
  
      MyViewModel myViewModel = session.Resolve&lt;MyViewModel&gt;(); //Autofac
      myiewModel.Init(id);
      BindingContext = myViewModel;
  }
  </code></pre>
  
  <p>Above, my View does its initialization, then resolves MyViewModel from Autofac DiC and then calls MyViewModel Init() method to do some additional setup on the VM.</p>
  
  <p>The Init method then calls my Async method GetDataAsync which return a IList like so:</p>
  
  <pre><code>public void Init()
  {
      // call this Async method to populate a ListView
      foreach (var model in GetDataAsync("111").Result)
      {
          // The List&lt;MyModel&gt; returned by the GetDataAsync is then
          // used to load ListView's ObservableCollection&lt;MyModel&gt;
          // This ObservableCollection is data-bound to a ListView in
          // this View.  So, the ListView shows its data once the View
          // displays.
      }
  }
  </code></pre>
  
  <p>, and here is my GetDataAsync() method including my comments:</p>
  
  <pre><code>public override async Task&lt;IList&lt;MyModel&gt;&gt; GetDataAsync(string id)
  {
      var timeout = TimeSpan.FromSeconds(20);
  
      try
      {
          byte[] messageBytes = GetMessageBytes(Id);
  
          using (var cts = new CancellationTokenSource(timeout))
          using (TcpClient client = new TcpClient(Ip, Port))
          using (NetworkStream stream = client.GetStream())
          {
              await stream.WriteAsync(messageBytes, 0, messageBytes.Length, cts.Token);
              await stream.FlushAsync(cts.Token);
  
              byte[] buffer = new byte[1024];
              StringBuilder builder = new StringBuilder();
              int bytesRead = 0;
  
              await Task.Delay(500);                 
              while (stream.DataAvailable) // need to Delay to wait for data to be available
              {
                  bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cts.Token);
                  builder.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, bytesRead));
              }
  
              string msg = buffer.ToString();
          }
  
          return ParseMessageIntoList(msg);  // parses message into IList&lt;MyModel&gt;
      }
      catch (OperationCanceledException oce)
      {
          return await Task.FromResult&lt;IList&lt;RoomGuestModel&gt;&gt;(new List&lt;RoomGuestModel&gt;());
      }
      catch (Exception ex)
      {
          return await Task.FromResult&lt;IList&lt;RoomGuestModel&gt;&gt;(new List&lt;RoomGuestModel&gt;());
      }
  }
  </code></pre>
  
  <p>I would expect that a ReadAsync or WriteAsync either complete successfully, throw some exception, or get cancelled after 10 seconds in which case I would catch OperationCanceledException.</p>
  
  <p><strong>However, it just hangs endlessly when I call method above.  If I am debugging and have some breakpoints in the code above, I will be able to go through the method entirely but if I call it 2nd time, app just hangs forever.</strong></p>
  
  <p><strong>I am new to Tasks and Async programming, so I am also not sure I do my cancellations and exception handling properly here?</strong></p>
  
  <p><strong>UPDATE AND FIX</strong></p>
  
  <p>I figured out how to fix the deadlock issue.  In hope this will help others sho might run into the same issue, I'll first explain it. The articles that helped me a lot are:</p>
  
  <p><a href="https://devblogs.microsoft.com/pfxteam/await-and-ui-and-deadlocks-oh-my/" rel="nofollow noreferrer">https://devblogs.microsoft.com/pfxteam/await-and-ui-and-deadlocks-oh-my/</a> by Stephen Taub
  <a href="https://montemagno.com/c-sharp-developers-stop-calling-dot-result/" rel="nofollow noreferrer">https://montemagno.com/c-sharp-developers-stop-calling-dot-result/</a> by James Montemagno
  <a href="https://msdn.microsoft.com/en-us/magazine/jj991977.aspx" rel="nofollow noreferrer">https://msdn.microsoft.com/en-us/magazine/jj991977.aspx</a> by StephenCleary
  <a href="https://blog.xamarin.com/getting-started-with-async-await/" rel="nofollow noreferrer">https://blog.xamarin.com/getting-started-with-async-await/</a> by Jon Goldberger</p>
  
  <p>@StephenCleary was great help understanding the issue.  Calling <code>Result</code> or <code>Wait</code> (above, I call <code>Result</code>  when calling <code>GetDataAsync</code>) <strong>will lead to dead-lock</strong>.  </p>
  
  <p>The context thread (UI in this case) is now waiting for <code>GetDataAsync</code> to complete, but <code>GetDataAsync</code> captures the current context-thread (UI thread), so it can resume on it once it gets data from TCP.  But since this context-thread is now blocked by call to <code>Result</code>, it cannot resume.  </p>
  
  <p>The end result is that it looks like call to <code>GetDataAsync</code> has deadlocked but in reality, it is call to <code>Result</code> that deadlocked.</p>
  
  <p>After reading tons of articles from @StephenTaub, @StephenCleary, @JamesMontemagno, @JoeGoldenberger (thank you all), I started getting understanding of the issue (I am new to TAP/async/await).  </p>
  
  <p>Then I discovered continuations in Tasks and how to use them to resolve the issue (thanks to Stephen Taub's article above).  </p>
  
  <p>So, instead of calling it like:</p>
  
  <pre><code>IList&lt;MyModel&gt; models = GetDataAsync("111").Result;
  foeach(var model in models)
  {
    MyModelsObservableCollection.Add(model);
  }
  </code></pre>
  
  <p>, I call it with continuation like this:</p>
  
  <pre><code>GetDataAsync(id)
      .ContinueWith((antecedant) =&gt;
      {
          foreach(var model in antecedant.Result)
          {
              MyModelsObservableCollection.Add(model);
          }
  
      }, TaskContinuationOptions.OnlyOnRanToCompletion)
      .ContinueWith((antecedant) =&gt;
      {
          var error = antecedant.Exception.Flatten();
      }, TaskContinuationOptions.OnlyOnFaulted);
  
  This seam to have fixed my deadlocking issue and now my list will load fine even though it is loaded from the constructor.  
  </code></pre>
  
  <p>So, this seam to work just fine.  But @JoeGoldenberger also suggests another solution in his article <a href="https://blog.xamarin.com/getting-started-with-async-await/" rel="nofollow noreferrer">https://blog.xamarin.com/getting-started-with-async-await/</a> which is to use <code>Task.Run(async()=&gt;{...});</code> and inside that await <code>GetDataAsync</code> and load <code>ObservableCollection</code>.  So, I gave that a try as well and that is not blocking either, so working great:</p>
  
  <pre><code>Task.Run(async() =&gt;  
  {
      IList&lt;MyModel&gt; models = await GetDataAsync(id);
      foreach (var model in models)
      {
          MyModelsObservableCollection.Add(model);
      }
  });
  </code></pre>
  
  <p>So, it looks like either of these 2 will remove deadlock just fine. And since above my Init method is called from a c-tor; therefore, I cannot make it Async and await on this, using one of the 2 methods described above resolves my problem.  I dont know which one is better but in my tests, they do work.</p>