This post originated from an RSS feed registered with .NET Buzz
by Udi Dahan.
Original Post: Asynchronous Callback R Us
Feed Title: Udi Dahan - The Software Simplist
Feed URL: http://feeds.feedburner.com/UdiDahan-TheSoftwareSimplist
Feed Description: I am a software simplist. I make this beast of architecting, analysing, designing, developing, testing, managing, deploying software systems simple.
This blog is about how I do it.
I'm sure a lot of people are familiar with the kind of asynchronous programming model supported by the .Net framework. The common API looks something like this:
public IAsyncResult BeginXXX (data, AsyncCallback callback, Object state);
The purpose of the "state" object is to allow you to put in some data that you'd like to get back with the callback. This is absolutely essential in the case where your code can fire off numerous asynchronous calls, and you need a way to differentiate one callback from another.
Which would result in client code looking like this:
public void OrderForm_onSubmitRequested(object sender, EventArgs e)
{
IOrderForm f = (IOrderForm)sender;
Order o = f.Order;
this.ServiceAgent.BeginSubmitOrder(o, new AsyncCallback(this.SubmitOrderCompleted), f);
f.Visible = false;
}
But, in the "SubmitOrderSucceded" method, you'd have to do an ugly cast on the "IAsyncResult.AsyncState" property to get back your IOrderForm. And I'm sure everyone will agree with me on this, it's a pretty clunky API.
Wouldn't it be nicer to write code like this:
public void OrderForm_onSubmitRequested(object sender, EventArgs e)
{
IOrderForm f = (IOrderForm)sender;
Order o = f.Order;
this.ServiceAgent.SubmitOrder(o).Completed += delegate(int errorCode)
{ this.SubmitOrderCompleted(errorCode, f); };
f.Visible = false;
}
Why is this nicer? Well, you get the method call separated from the callback declaration. Not to mention the nice code completion features of the IDE for events, which you don't have for plain old delegates.
If you want to implement this kind of API in your own code, you need to do some anonymous delegate tricks yourself. It's pretty amazing that you can get two sequential callstacks to communicate - since the method call, and the event subscription are really two separate calls.
But you'll have to wait for the next post to see how it's done... :)