WCF Asynchronous Methods with Return Types

Nate Bross

Contributor
Joined
Apr 6, 2005
Messages
601
Location
Chicago, IL
I'm having trouble with WCF Async service methods. I think this is a lack of understanding on my part, but I can't find anything that applies to my situation.

In short I would like to call a method and then perform work after getting the value.

To simplify my situation imagine this:

Form with two buttons and two listboxes.

Click button 1, and it calls the WCF and populates list 1;

Click button 2, and it calls the WCF and populates list 2;


In a typical situation, I would do this:

Code:
button1_handler
{
    listBox1.ItemsSource = dal.GetList("button1");
}
button2_handler
{
    listBox1.ItemsSource = dal.GetList("button2");
}

the issue is this, in the Asnyc world I can't do that sicne the Async methods do not have return types but use callbacks.

Code:
dal.GetListComplete += (object sender, GetListEventArgs e) => 
{
    // here I must pick list one or two -- with no easy way 
    // to know which button was clicked,
    listBox1.ItemsSource = e.Result;
};
//populate list of all Client OUs
dal.GetList("button1");

I have the same issue even if I do not use an anonymous method for the event handler.

If I use the (sender) object, it seems very wasteful to make a large switch statement in the completed event handler to determin what list I should populate.

Any thoughts or ideas are really appreciated!
 
One of the overloaded versions of the async method accepts a user state parameter (just object). You can pretty much shove anything yuo want in there and then access it via the <whatever>EventArgs parameter in the event handler.

When calling the async method you could pass in the control you want to assign the results to in the UserState parameter and then cast it back to a ListControl in the event handler.
 
Putting the control in that userstate looks like the best option, thanks. It hadn't occured to me to put an object in there.

It still doesn't seem as clean as

Code:
...code...
Object.ItemsSource = WCFService.TheMethod(theParm);
...code...

but I understand that with an async method there cannot be a return type.
 
Managing your own synchronicity

Using asynchronous methods is never going to be as simple as using synchronous methods, and you are unlikely to ever get language that supports what you are suggesting. To have an assignment which completes non-deterministically would probably lead to some very difficult to diagnose bugs!

A different approach would be to handle the synchronicity yourself - kick off the operation a new thread directly from the button event handlers, and then use synchronous methods to do the work:

C#:
void button1_handler(object sender, EventArgs e) {
    ThreadPool.QueueUserWorkItem(PopulateList, "button1");
}
void button2_handler(object sender, EventArgs e) {
    ThreadPool.QueueUserWorkItem(PopulateList, "button2");
}

void PopulateList(object state) {
    listBox1.ItemsSource = dal.GetList((string) state);

    //Do other work here
}

This keeps the program flow nice and logical.

Good luck :cool:
 
Yes, I understand that asynchronous methods cannot have return types, because if they did, they would not be asynchronous.

I'm using Silverlight 2 so, I only have the Async methods available to me so PD's sugestion to stuff the object I want to do work on in the UserState is the best option available to me at this point.

Thanks again for the responses.
 
Back
Top