UI responsiveness using tasks (.NET 4.0 vs .NET 4.5)

I have a Winforms application that gets data from using request/response calls to WCF service and of course I want it to be responsive when doing long running calls. I decided to use Tasks. Below is an example of what I was doing to make my asynchronous calls to the WCF service .

.NET 4.0 Example

This example below is long and tedious but it did what I needed and it was still using tasks.

#Region "Buttons"
    Private Async Sub btnCompleteSurvey_ItemClick(sender As Object, e As EventArgs) Handles btnRefresh.ItemClick
        Try
            LoadingPanel.Visible = True
            CompleteSurveyAsync("TalkDotNet", 12, False, Nothing, AddressOf CompleteSurveyAsyncResult)
        Catch ex As Exception
            LoadingPanel.Visible = False
            ' Log the exception here
        End Try
    End Sub
#End Region

#Region "Completed Requests"
    Private Sub CompleteSurveyAsyncResult(Successful As Boolean, Result As Boolean, Exc As Exception, UserState As Object)
        Try
            If Me.InvokeRequired Then
                Dim oDel As New CompleteSurveyAsyncResult(AddressOf CompleteSurveyAsyncResult)
                Me.BeginInvoke(oDel, New Object() {Successful, Result, Exc, UserState})
            Else
                Try
                    If Successful Then
                        MessageBox.Show("Thank-you for completing the survey", "Survey complete")
                    Else
                        'Notify administrator
                        'Some code here
                        'Notify end user
                        MessageBox.Show("An error occurred when trying to save your survey.", "Error")
                    End If
                Finally
                    LoadingPanel.Visible = False
                End Try
            End If
        Catch ex As Exception
            ' Log the exception here
        End Try
    End Sub
#End Region

#Region "Async WCF Operation"
    Public Delegate Sub CompleteSurveyAsyncResult(Successful As Boolean, Result As Boolean, Exc As Exception, UserState As Object)
    Public Shared Sub CompleteSurveyAsync(username As String, surveyID As Integer, ignored As Boolean, UserState As Object, oDelegate As CompleteSurveyAsyncResult)
        Dim oResult As Boolean = Nothing
        Try
            System.Threading.Tasks.Task.Factory.StartNew(Function()
                                                             Try
                                                                 Dim WCFServiceClient = New WCFServiceClient()
                                                                 oResult = WCFServiceClient.CompleteSurvey(username, surveyID, ignored)
                                                                 oDelegate.Invoke(True, oResult, Nothing, UserState)
                                                             Catch ex As Exception
                                                                 'Throws Exception if WCF call fails.
                                                                 oDelegate.Invoke(False, oResult, ex, UserState)
                                                             End Try

                                                         End Function)
        Catch ex As Exception
            'Throws an Exception if Task cannot be created
            oDelegate.Invoke(False, oResult, ex, UserState)
        End Try
    End Sub
#End Region
.NET 4.5 Example

The example below uses .NET 4.5’s Async Await features and as you can see. A much easier way of doing any asynchronous operation. The main thing here to look out for is the Async and Await keywords.

#Region "Buttons"
    Private Async Sub btnCompleteSurvey_ItemClick(sender As Object, e As EventArgs) Handles btnRefresh.ItemClick
        Try
            LoadingPanel.Visible = True
            Dim bSaved As Boolean = Await CompleteSurveyAsync("TalkDotNet", 12, False)
            If bSave Then
                MessageBox.Show("Thank-you for completing the survey", "Survey complete")
            Else
                'Notify administrator
                'Some code here
                'Notify end user
                MessageBox.Show("An error occurred when trying to save your survey.", "Error")
            End If
        Catch ex As Exception
            ' Log the exception here
        Finally
            LoadingPanel.Visible = False
        End Try
    End Sub
#End Region

#Region "Async WCF Operation"
    Public Async Function CompleteSurveyAsync(username As String, surveyID As Integer, ignored As Boolean) As Task(Of Boolean)
        Return Await Task.Run(Of Boolean)(Function()
                                              Dim WCFServiceClient = New WCFServiceClient()
                                              Return WCFServiceClient.CompleteSurvey(username, surveyID, ignored)
                                          End Function)
    End Function
#End Region

Some more information about .NET 4.5’s Async Await can be found on MSDN

Asynchronous Programming with Async and Await (C# and Visual Basic)

Best Practices in Asynchronous Programming

Best Practices in Asynchronous Programming

Leave a comment