views:

59

answers:

5

I have a webservice method getContactsAsync. I've understood that when it's completed it's supposed to raise an event. How can I (still asynchronously) find out when the method is done and use the result?

public void GetContacts()
{
    webService.getContactsAsync()
}

public void GetContactsCompleted(object sender, getContactsAsyncCompletedEventArgs e)
{
    contacts = e.Result;
}

I don't get how I'm supposed to use this. The way I can think of is to call GetContacts and then with a while-loop check if contacts != null to know when it has completed. But this will lock up the thread.

Is there some kind of best-practice typical for this situation? Thanks for reading!

If I'm completely out of it feel free to explain how it actually works :)

A: 

I'm not familiar with that method, sounds specific to that web-service. However, to point you in the right direction, most Async methods take in a delegate as a parameter and will call that delegate when it has finished.

Depending on the method, there may be parameters to call for errors, status and so on.

It's hard to get more specific than that without more specific information about your situation.

David Culp
It appears that he's using the Event-based async pattern, not the APM pattern; this raises an event on completion, rather than executing an AsyncCallback.
Bradley Grainger
I edited my question as I more and more realized what my problem was and what I wanted to accomplish. David answered to my original question which was a bit confused at the best. I'm still confused with all this but am learning as I go.
Phil
+1  A: 

If you are using SOAP-based web services via a Web Reference, this resource may be the ticket.

http://msdn.microsoft.com/en-us/library/wyd0d1e5%28VS.80%29.aspx

Another viable approach is to use the synchronous methods of the service from your own background thread.

kbrimington
A: 

Take a look at Calling Web Services Asynchronously.

XIII
A: 

It's a bit hard to figure out from your question where the problem lies.

You can keep track of when the operation completes by setting something in the event handler. In your example code, you're setting contacts, so you could just check if contacts is null.

If you want an asynchronous notification of completion, like an event that triggers when the operation completes, then... er... handle GetContractsCompleted, because that's exactly what it's there for.

If there's something more specific that you'd like (e.g., a WaitHandle that is signalled or a Task that completes when the operation completes), then that can be done but it's a bit more work.

Stephen Cleary
+1  A: 

Each DoSomethingAsync method has a corresponding DoSomethingCompleted event that is raised when the method finishes. (See Event-based Asynchronous Pattern Overview for more information.) You need to attach your event handler method to the webService.GetContactsCompleted event in order for it to be executed:

public void GetContacts()
{
    webService.getContactsCompleted += GetContactsCompleted;
    webService.getContactsAsync();
}

// NOTE: Should be a private method.
private void GetContactsCompleted(object sender, getContactsAsyncCompletedEventArgs e)
{ /* ... */ }

(Note that you will need to ensure that the event handler is only attached once, or it will start being invoked multiple times when the method finishes.)

Bradley Grainger
How to ensure that the event handler is only attached once? Some kind of singleton pattern? Thanks everyone!
Phil
You can ensure it's only happens once by attaching it immediately after instantiating the `webService` object (e.g., in this class' constructor).
Bradley Grainger