MSDN Documentation

Asynchronous Programming with Async/Await in VB.NET

Asynchronous programming allows your application to perform long-running operations without blocking the main thread, leading to a more responsive user interface and improved performance. VB.NET provides the Async and Await keywords to simplify asynchronous programming.

Introduction to Async/Await

The Async keyword is used to declare a method as asynchronous. An asynchronous method can execute asynchronously with respect to the caller. The Await operator is applied to an awaitable expression (typically a call to another asynchronous method) and pauses the execution of the async method until the awaited task completes. While waiting, the method yields control to the caller, allowing other operations to proceed.

Key Concepts:

  • Async: Marks a method as asynchronous.
  • Await: Pauses execution until an awaitable operation completes.
  • Task-based Asynchronous Pattern (TAP): The underlying pattern used by Async/Await.

Declaring Async Methods

To declare a method as asynchronous, simply add the Async keyword before the Sub or Function keyword:


Public Async Function DownloadDataAsync(url As String) As Task(Of String)
    ' ... asynchronous operation ...
    Await Task.Delay(1000) ' Simulate a delay
    Return "Data downloaded successfully."
End Function

Public Async Sub ProcessDataAsync()
    Console.WriteLine("Starting data processing...")
    Dim result As String = Await DownloadDataAsync("http://example.com/data")
    Console.WriteLine($"Processing result: {result}")
    Console.WriteLine("Data processing finished.")
End Sub
            

An asynchronous method typically returns:

Using the Await Operator

The Await operator can only be used inside an Async method. It is applied to an awaitable expression, which is typically a method that returns a Task or Task(Of TResult).


Public Async Function FetchUserData(userId As Integer) As Task(Of User)
    Dim client As New HttpClient()
    Dim jsonResponse As String = Await client.GetStringAsync($"https://api.example.com/users/{userId}")
    ' Deserialize jsonResponse to User object
    Dim user As User = DeserializeJson(jsonResponse)
    Return user
End Function

Public Async Sub DisplayUser(userId As Integer)
    Try
        Dim user As User = Await FetchUserData(userId)
        Console.WriteLine($"User Name: {user.Name}")
        Console.WriteLine($"User Email: {user.Email}")
    Catch ex As Exception
        Console.WriteLine($"Error fetching user: {ex.Message}")
    End Try
End Sub
            

Benefits of Async/Await

Tip:

Always use the Async suffix for method names that are asynchronous. This convention makes it easier to identify asynchronous methods.

Common Pitfalls and Best Practices

Example: Downloading Multiple Files

This example demonstrates downloading multiple files concurrently:


Public Async Function DownloadFilesAsync(urls As IEnumerable(Of String)) As Task
    Dim downloadTasks As New List(Of Task)()

    For Each url As String In urls
        downloadTasks.Add(DownloadSingleFileAsync(url))
    Next

    Await Task.WhenAll(downloadTasks)
    Console.WriteLine("All files downloaded.")
End Function

Private Async Function DownloadSingleFileAsync(url As String) As Task
    Dim client As New HttpClient()
    Dim fileName As String = Path.GetFileName(New Uri(url).LocalPath)
    Dim content As Byte() = Await client.GetByteArrayAsync(url)
    ' Save the content to a file
    Await File.WriteAllBytesAsync(fileName, content)
    Console.WriteLine($"Downloaded: {fileName}")
End Function

' Usage:
' Dim urls = New List(Of String) From {"http://example.com/file1.zip", "http://example.com/file2.txt"}
' Await DownloadFilesAsync(urls)