title: C# - understanding async/await
body: <p>The C# documentation on asynchronous programming states that:</p>
  
  <ul>
  <li><p>For CPU-bound code, you await an operation which is started on a background thread with the <code>Task.Run</code> method.</p></li>
  <li><p>The <code>await</code> keyword is where the magic happens. It yields control to the caller of the method that performed <code>await</code>, and it ultimately allows a UI to be responsive or a service to be elastic.</p></li>
  <li><p>When the <code>await</code> keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete.</p></li>
  </ul>
  
  <p>With that in mind, I tested some CPU bound code <em>(finding a Bitcoin block hash seemed suitably modern and difficult)</em> to try and understand exactly what is happening when async/await is applied:</p>
  
  <p><strong>Example</strong></p>
  
  <pre><code>namespace AsyncronousSample
  {
      using System;
      using System.Linq;
      using System.Security.Cryptography;
      using System.Threading.Tasks;
  
      internal static class Program
      {
          private static async Task Main(string[] args)
          {
              string result = await HashAsync(Guid.NewGuid().ToByteArray(), 4);
  
              Console.WriteLine("Calculating hash...");
              Console.WriteLine(result);
  
              Console.Read();
          }
  
          private static async Task&lt;string&gt; HashAsync(byte[] data, int difficulty = 1)
          {
              int nonce = default;
              string result = default;
  
              byte[] GetDataBytesWithNOnce()
              {
                  return data
                      .Concat(BitConverter.GetBytes(nonce++))
                      .ToArray();
              }
  
              byte[] ComputeHash(byte[] bytes)
              {
                  using (SHA256 sha = SHA256.Create())
                  {
                      return sha.ComputeHash(sha.ComputeHash(bytes));
                  }
              }
  
              string ConvertToHash(byte[] hashBytes)
              {
                  return BitConverter
                      .ToString(hashBytes)
                      .Replace("-", string.Empty)
                      .ToLower();
              }
  
              return await Task.Run(() =&gt;
              {
                  do
                  {
                      result = ConvertToHash(ComputeHash(GetDataBytesWithNOnce()));
                  } while (!result.StartsWith(new string('0', difficulty)));
  
                  return result;
              });
          }
      }
  }
  </code></pre>
  
  <p>Okay, for the more astute of you, who are interested in Bitcoin and how it works, this isn't the <em>real</em> Bitcoin hash algorithm, but it is <code>SHA256(SHA256(data + nonce))</code>, so it's difficult enough for the example.</p>
  
  <p><strong>Expectation versus Reality</strong></p>
  
  <p>I expected that <code>Calculating hash...</code> would be printed immediately to the console, and the result would then print when the hash had finally been found. </p>
  
  <p>In reality, nothing is printed to the console until the hash is found.</p>
  
  <p><strong>Question</strong></p>
  
  <p>Where have I gone wrong in my understanding, or my code?</p>