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