August 23, 2014, 1:27 pm
Well, I couldn’t let this rest, so here is an even simpler example of doing Async Await in VB.NET.
For this example code, I created a simple forms application with two buttons named cmdSynchronous and cmdAsynchronous, a label called lblStatus, and just to demonstrate the UI locking up effect, a combo box with some entries in it. Here is the code behind this form:
Public Class Form1
Sub LongOperation()
Threading.Thread.Sleep(5000)
End Sub
Private Sub cmdSynchronous_Click(sender As Object, e As EventArgs) Handles cmdSynchronous.Click
lblStatus.Text = "Running a long operation synchronously... (UI thread should lock up)"
Application.DoEvents() ' needed here so that the label will update
LongOperation()
lblStatus.Text = "Done running the long operation synchronously."
End Sub
Private Async Sub cmdAsynchronous_Click(sender As Object, e As EventArgs) Handles cmdAsynchronous.Click
lblStatus.Text = "Running a long operation asynchronously... (UI thread should be fully responsive)"
Await Task.Run(Sub()
LongOperation()
End Sub)
lblStatus.Text = "Done running the long operation asynchronously."
End Sub
End Class |
Public Class Form1
Sub LongOperation()
Threading.Thread.Sleep(5000)
End Sub
Private Sub cmdSynchronous_Click(sender As Object, e As EventArgs) Handles cmdSynchronous.Click
lblStatus.Text = "Running a long operation synchronously... (UI thread should lock up)"
Application.DoEvents() ' needed here so that the label will update
LongOperation()
lblStatus.Text = "Done running the long operation synchronously."
End Sub
Private Async Sub cmdAsynchronous_Click(sender As Object, e As EventArgs) Handles cmdAsynchronous.Click
lblStatus.Text = "Running a long operation asynchronously... (UI thread should be fully responsive)"
Await Task.Run(Sub()
LongOperation()
End Sub)
lblStatus.Text = "Done running the long operation asynchronously."
End Sub
End Class
Notice that both button click events call the LongOperation method, which just sleeps for 5 seconds. However, the synchronous button click will lock up the UI (try to open the combo box, you will see that it waits until the sleep is done before displaying the choice list), whereas the asynchronous one will not.
Now in general, you would probably want to keep the tasks from piling up, as they would if you keep clicking the asynchronous button. I leave this as an exercise to the reader on preventing this problem.
BTW, Happy Birthday to Gary Hoey and Terje Rypdal, two of my favorite guitarists.
August 16, 2014, 11:21 am
I scoured the interwebs looking for a VB.NET simple Async Await example, and kind of came up empty. So, I decided to try to use bits and pieces of the examples I could find to roll my own.
The background here is that I am working on an application that accesses resources on the internet, and did not want to block the UI while the communications code was running.
Here is the code that I came up with:
Async Function GetDetails(theID As String) As Task
Dim url As String
url = GET_DETAILS_URL & "?theid=" & theID
Dim request As WebRequest = WebRequest.Create(url)
Dim response As WebResponse = Await request.GetResponseAsync()
Dim dataStream As Stream = response.GetResponseStream()
Dim reader As New StreamReader(dataStream)
Dim responseFromServer As String = reader.ReadToEnd()
reader.Close()
response.Close()
' do something here with responseFromServer
End Function
Async Sub lstItems_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstItems.SelectedIndexChanged
Dim idx As Integer = lstItems.SelectedIndex
' get the selected item
Dim theItem As Object = itemsList(idx)
Dim theItemID As String = theItem.itemID.ToString()
Await GetDetails(theItemID)
End Sub |
Async Function GetDetails(theID As String) As Task
Dim url As String
url = GET_DETAILS_URL & "?theid=" & theID
Dim request As WebRequest = WebRequest.Create(url)
Dim response As WebResponse = Await request.GetResponseAsync()
Dim dataStream As Stream = response.GetResponseStream()
Dim reader As New StreamReader(dataStream)
Dim responseFromServer As String = reader.ReadToEnd()
reader.Close()
response.Close()
' do something here with responseFromServer
End Function
Async Sub lstItems_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstItems.SelectedIndexChanged
Dim idx As Integer = lstItems.SelectedIndex
' get the selected item
Dim theItem As Object = itemsList(idx)
Dim theItemID As String = theItem.itemID.ToString()
Await GetDetails(theItemID)
End Sub
BTW, Happy Bennington Battle Day to our Green Mountain friends.