title: Use await without async to process tasks as they complete
body: <p>Just getting into asynchronous programming and my end goal is to get the sha1 hashes of given set of files asynchronously and then continue processing said files with the computed hash value . I found the following MSDN blog post speaks on how to process the task results as the tasks finish: <a href="http://blogs.msdn.com/b/pfxteam/archive/2012/08/02/processing-tasks-as-they-complete.aspx" rel="nofollow">Link</a></p>
  
  <p>The entire article is written in C# and my project is in VB.NET. I have attempted to rewrite the C# code to VB myself, however I must be missing a critical step or I am not fully understanding the process/syntax of <code>Async</code>/<code>Await</code> programming.</p>
  
  <p>I am receiving the following error on the following lines:</p>
  
  <blockquote>
    <p>Error 1   'Await' can only be used when contained within a method or lambda expression marked with the 'Async' modifier.
    </p>
  </blockquote>
  
  <pre class="lang-vb prettyprint-override"><code>Dim t As Task(Of Integer) = Await bucket
  Dim result As Integer= Await t
  
  Dim t As Task(Of String) = Await bucket
  Dim result As String = Await t
  </code></pre>
  
  <p>I can make the error go away by adding <code>Async</code> to the containing Sub declaration. However, if I do that I receive another error because the containing method is <code>main()</code> and it's a console Application. </p>
  
  <blockquote>
    <p>Error 1   The 'Main' method cannot be marked 'Async'.</p>
  </blockquote>
  
  <p>So I guess my question is, how can I use <code>Await</code> an asynchronous task without making the containing method Async? My code below is just a tester for implementation in a WinForms project and I'd rather stay away from non native .NET pieces.</p>
  
  <p>Below is the full code that I have converted from C# along with my little bit of code that does the computing of the sha1 hashes for the files:</p>
  
  <pre class="lang-vb prettyprint-override"><code>Option Strict On
  Option Explicit On
  
  Imports System.IO
  Imports System.Threading
  Imports System.Threading.Tasks
  
  
  Module Module1
  
      Async Sub main()
          ' From the MSDN article
          Dim taskArr As Task(Of Integer)() = {Task(Of Integer).Delay(3000).ContinueWith(Function(x) 3I), _
                                             Task(Of Integer).Delay(1000).ContinueWith(Function(x) 1I), _
                                             Task(Of Integer).Delay(2000).ContinueWith(Function(x) 2I), _
                                             Task(Of Integer).Delay(5000).ContinueWith(Function(x) 5I), _
                                             Task(Of Integer).Delay(4000).ContinueWith(Function(x) 4I)}
  
          For Each bucket As Task(Of Task(Of Integer)) In Interleaved(taskArr)
              Dim t As Task(Of Integer) = Await bucket  ' Error Here
              Dim result As Integer = Await t  ' Error Here
              Console.WriteLine("{0}: {1}", DateTime.Now, result)
          Next
  
          'My bit of code for computing the file hashes
          Dim tasks As New List(Of Task(Of String))
          Array.ForEach(New DirectoryInfo("C:\StackOverflow").GetFiles("*", SearchOption.AllDirectories), Sub(x) tasks.Add(getHashAsync(x)))
  
          For Each bucket As Task(Of Task(Of String)) In Interleaved(tasks)
              Dim t As Task(Of String) = Await bucket  ' Error Here
              Dim result As String = Await t  ' Error Here
              Console.WriteLine(result)
          Next
      End Sub
  
      ' Original C# code that I converted to VB myself
      Public Function Interleaved(Of T)(tasks As IEnumerable(Of Task(Of T))) As Task(Of Task(Of T))()
          Dim inputTasks As List(Of Task(Of T)) = tasks.ToList()
          Dim buckets() As TaskCompletionSource(Of Task(Of T)) = New TaskCompletionSource(Of Task(Of T))(inputTasks.Count - 1I) {}
          Dim results() As Task(Of Task(Of T)) = New Task(Of Task(Of T))(buckets.Length - 1I) {}
  
          For i As Integer = 0I To buckets.Count - 1I Step 1I
              buckets(i) = New TaskCompletionSource(Of Task(Of T))()
              results(i) = buckets(i).Task
          Next
  
          Dim continuation As New Action(Of Task(Of T))(Function(completed As Task(Of T))
                                                            Dim bucket As TaskCompletionSource(Of Task(Of T)) = buckets(Interlocked.Increment(-1I))
                                                            Return bucket.TrySetResult(completed)
                                                        End Function)
  
          For Each inputTask As Task(Of T) In inputTasks
              inputTask.ContinueWith(continuation, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default)
          Next
  
          Return results
      End Function
  
      ' Get the sha1 hash of the file
      Private Async Function getHashAsync(fle As FileInfo) As Task(Of String)
          Using strm As New IO.FileStream(fle.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
              Return Await New Task(Of String)(Function() As String
                                                   Dim sb As New Text.StringBuilder()
                                                   Using sha1 As New System.Security.Cryptography.SHA1CryptoServiceProvider()
                                                       Array.ForEach(sha1.ComputeHash(strm), Sub(x As Byte) sb.Append(x.ToString("x2")))
                                                   End Using
                                                   Return sb.Append(" | ").Append(fle.FullName).ToString
                                               End Function)
          End Using
  
      End Function 
  
  End Module
  </code></pre>