New.NET Async Control Flow Explained
Alan Berman recently detailed the new .NET Async feature’s control flow. On the Visual Basic Team site he explained that the Async feature allows the calling code and the response code to be in the same place. This is possible due to the Async and Await keywords. Async marks a function as returning an asynchronous task and Await transfers control flow back to the calling function until a task has completed.
Use of an Async function requires two task objects; one for the function marked Async and another for the real asynchronous operation taking place. When Await is called on a task within an Async function control is instantly returned to the calling function. When the real asynchronous call completes, a new thread picks up execution after the Await call. Await cannot be called on a task outside of a function marked Async. The code below extends the example found on the Visual Basic Team Site.
ShowInfo("In Main before Async call")
Dim task As Task(Of String) = GetWebPageAsync("http://www.msdn.com/")
ShowInfo("In Main after Async call", task.Id)
Dim content As String = task.Result 'Pauses until the result is available (synchronous)
ShowInfo("In Main after Async call has completed", task.Id)
Private Async Function GetWebPageAsync(ByVal webAddress As String) As Task(Of String)
Dim theTask As Task(Of String) = New WebClient().DownloadStringTaskAsync(New Uri(webAddress))
ShowInfo("In GetWebPageAsync before Await", theTask.Id)
Dim result As String = Await theTask ' returns to the calling function
ShowInfo("In GetWebPageAsync After Await", theTask.Id)
Private Sub ShowInfo(ByVal msg As String, Optional taskId As Integer = 0)
Console.WriteLine("Thread ID: " & System.Threading.Thread.CurrentThread.ManagedThreadId & " " & msg & IIf(taskId = 0, "", " task: " & taskId.ToString))
Thread ID: 8 In Main before Async call
Thread ID: 8 In GetWebPageAsync before Await task: 1
Thread ID: 8 In Main after Async call task: 2
Thread ID: 13 In GetWebPageAsync After Await task: 1
Thread ID: 8 In Main after Async call has completed task: 2
Note that once Await is called, the primary thread is finished with the Async method. When the asynchronous web request completes, a different thread handles processing the remainder of the Async method. The main thread’s request for the result blocks until the Async method completes. This feature is available as part of the Async CTP for VB.NET and C#.