Async Webservice


Michael Evans

Trying to call i webmethod asyncronizly and set the result to a datagrid.
It's not working any ideas


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim ws As New ReportingWS.APQReportingServices()

Dim cb As AsyncCallback = New AsyncCallback(AddressOf webcall)

Dim ar As IAsyncResult = ws.BeginGetAPQReports(cb, ws)

Dim intI As Integer

For intI = 1 To 1000

Me.TextBox1.AppendText(CStr(intI) & vbCrLf)


End Sub

Private Sub webcall(ByVal ar As IAsyncResult)

'Get the returned web service instance

Dim ws As New ReportingWS.APQReportingServices()

Dim ds As New DataSet()

Me.DataGrid1.DataSource = CType(Me.Invoke(ar), DataSet)

End Sub



Andrew Hopper

Hello, Michael-

Welcome to the slightly more complex world of async Web Services
programming! We'll having you writing snappy, responsive UIs in no time.

In order to obtain the results of the asynchronous call, you always need to
call the corresponding EndXXX call and pass that call the IAsyncResult
object you obtained from the BeginXXX call (or as the parameter to an
AsyncCallback handler). In addition, if you are using the callback method
approach, you may receive the callback on a thread that is not the WinForms
UI thread. It is a Bad Thing to touch properties and/or methods from a
thread that is not the UI thread, so to be safe you'll need to either check
InvokeRequired and Invoke when necessary or just blindly use Invoke (that
approach doesn't perform as well, but it's simpler to write).

As an example, let's modify the code you provided in your AsyncCallback

Private Sub webcall(ByVal ar As IAsyncResult)
Dim ws As ReportingWS.APQReportingServices
Dim ds As DataSet

' Get a reference to the Web Service proxy we were using for the
' asynchronous call, which we thoughtfully stuffed into AsyncState
ws = DirectCast(ar.AsyncState, ReportingWS.APQReportingServices)

' Get the resulting DataSet from the async call, passing
' the IAsyncResult object to the EndXXX call. You can have
' multiple calls to the same method pending, and this tells the callee
' which async call we're interested in retrieving the results for.
ds = ws.EndGetAPQReports(ar)

' Set the DataSource using a delegate since we could
' be on the wrong thread in this handler
Me.Invoke(new SetDataSourceHandler(Me.SetDataSource, new Object() {ds}))
End Sub

' The following is necessary to make sure we populate
' the DataGrid control's DataSource property on the right
' thread. The gods of WinForms become angered when you
' tickle properties/methods from the wrong thread.

' A delegate for our property-setter
Private Delelgate Sub SetDataSourceHandler(ByVal ds As DataSet)

' Our extremely complex property-setter
Private Sub SetDataSource(ByVal ds As DataSet)
Me.DataGrid1.DataSource = ds
End Sub

Hope this helps!
Andy Hopper



Andrew Hopper

Wups, that'll teach me to write code on the fly.

Change the Invoke line from:
Me.Invoke(new SetDataSourceHandler(Me.SetDataSource, new Object() {ds}))

Me.Invoke(New SetDataSourceHandler(AddressOf SetDataSource), New Object()


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question