Asynchronous Programming Patterns and Techniques - No Concensus?

F

Frankie

For the first time with my .NET programming endeavors I need to add
asynchronous processing capabilities to a library. Before this I was using
old-fashioned callbacks. Anyway I was just now doing a bunch of research on
my alternatives before I begin to write code. My question below is of a
general level - so I don't think my particular requirements are relevant.
But in case you're wondering, I'm writing a library in support of a Windows
Forms app that, amongst other things, connects to a SQL Server database and
executes bunch of scripts. While those scripts are executing, the Windows
Forms app users should be able to do other work.

Anyway...

According to MSDN online, it appears that there are 2 identified patterns we
can follow when implementing asynchronous processing, in addition to a few
additional techniques [that don't really amount to being patterns].

Beyond simply calling BeginInvoke on a delegate, and dealing with that
scenario, two asynchronous programming design patterns documented in MSDN
online include:
"IAsyncResult Pattern"
and
"Event-based Asynchronous Pattern"

When going to add asynchronous processing capabilities to our libraries,
According to the MSDN docs online (links provided if you want them), we are
supposed to always implement the "event-based" pattern, and only implement
the "IAsyncResult pattern" only if absolutely necessary. MSDN goes on and on
and on about how we should do whatever possible to avoid the "IAsyncResult
pattern", and even when we have to implement it, we have to go through a
bunch of gyrations and STILL ALSO implement the "event-based" pattern.

So that's MSDN. Given the foreboding tone of the MSDN treatment, I looked to
the book Framework Design Guidelines (by Cwalina and Abrams) figuring they'd
shed some light on the subject, and they do. Chapter 9 section 2 presents
ONLY the Async pattern.... nowhere does the book talk about the
"Event-based" pattern glorified by MSDN - at least not that I found. So
apparently the guys who wrote the .NET Framework, itself, don't give a hoot
about this "Event-based" pattern that MSDN suggests will save the world.

So, I'd appreciate some general guidance from those of you who actually have
implemented asynchronous processing in your applications, if such guidance
can be had. I know "it all depends" - but I'd sure appreciate something more
specific than that, if possible.

Thanks!
 
P

Peter Duniho

Frankie said:
[...]
When going to add asynchronous processing capabilities to our libraries,
According to the MSDN docs online (links provided if you want them), we are
supposed to always implement the "event-based" pattern, and only implement
the "IAsyncResult pattern" only if absolutely necessary. MSDN goes on and on
and on about how we should do whatever possible to avoid the "IAsyncResult
pattern", and even when we have to implement it, we have to go through a
bunch of gyrations and STILL ALSO implement the "event-based" pattern.

I assume you are talking about this page:
http://msdn2.microsoft.com/en-us/library/ms228966.aspx

IMHO, if you're going to reference online documentation in a post, you
should just include the links as a matter of course.

As far as the question, I don't get the same "we have to go through a
bunch of gyrations" vibe that you do. But I guess that's a matter of
opinion.

What I do see is a suggestion that, since an asynchronous pattern may
rely on IAsyncResult anyway, that it is tempting to expose that in the
higher-level API of the class. They seem to be trying to nudge
developers away from exposing that, and instead using events.

There is also the hint that using IAsyncResult would perform better than
using events. While I see a potential for a negligible performance
difference, it's not clear to me where one would wind up seeing such a
large performance difference so as to make that a part of the basic API
design decision-making process. Maybe someone else can clarify that part.
So that's MSDN. Given the foreboding tone of the MSDN treatment, I looked to
the book Framework Design Guidelines (by Cwalina and Abrams) figuring they'd
shed some light on the subject, and they do. Chapter 9 section 2 presents
ONLY the Async pattern.... nowhere does the book talk about the
"Event-based" pattern glorified by MSDN - at least not that I found. So
apparently the guys who wrote the .NET Framework, itself, don't give a hoot
about this "Event-based" pattern that MSDN suggests will save the world.

You speak a lot of "tone", and yet the tone in your own post carries a
lot of baggage. "Foreboding", "gyrations", "save the world"? I find
none of this in the documentation, and frankly I object to documentation
that does include that sort of subjective commentary (and yes, I've run
into documentation like that, but MSDN is generally free of it).
So, I'd appreciate some general guidance from those of you who actually have
implemented asynchronous processing in your applications, if such guidance
can be had. I know "it all depends" - but I'd sure appreciate something more
specific than that, if possible.

IMHO, the biggest reason to use events is if you're doing to have
multiple subscribers. I don't find the IAsyncResult pattern all that
unwieldy, especially from the client side of things. And if you are, as
MSDN suggests, going to implement the underlying async behavior using an
IAsyncResult-like architecture anyway, it seems like exposing it would
be fine.

But events are IMHO slightly simpler to grasp at first, they are more
consistent with the bulk of the Forms-related API, and they do allow for
multiple subscribers with respect to async operations, even if one often
would not need that functionality.

On the other hand, if your design wants to ensure only one method at
most will receive notification of the end of an async operation, you
would probably want to stay away from the event-based model.

The biggest disconnect I have is the implication that I would be
implementing an async pattern based on an IAsyncResult in the first
place, as well as the statement that "it is rare" to see IAsyncResult
without a parallel event pattern. I can't explain why they would write
that, since I can think of plenty of counter-examples to both ideas.

I can agree that the docs aren't offering much in the way of productive
advice regarding which pattern to use, but I'd disagree that it's being
so event-bigoted as you seem to be suggesting.

Which is better? It depends.

Sorry, you asked for it. :)

Pete
 
F

Frankie

Thanks Peter....


Yes - that's the specific link.
IMHO, if you're going to reference online documentation in a post, you
should just include the links as a matter of course.

Yes - I guess I didn't because I didn't want for the post to come across as
"you have to read this link in order for this post to make senese." I'm sure
you've seen that before.... posts that go something like "tell me how to
implement the gee whiz feature at this link...."

You speak a lot of "tone", and yet the tone in your own post carries a lot
of baggage. "Foreboding", "gyrations", "save the world"?

Okay, fair enough on the "tone" part of my OP. But back to the MSDN doc...
they are very explicit about their recommendations yet give little or no
explanation. Recommendations usually come with explanation. The following
aren't very enlightening (from the above link):
<quote>
Do not expose the IAsyncResult pattern without also exposing the
event-based pattern.
</quote>
then
<quote>
If you must expose both the event-based pattern and IAsyncResult pattern
on a single calss, use the EditorBrowsableAttribute set to Advanced to mark
the IAsyncResult pattern implementation as an advanced feature... blah blah
blah
</quote>

Okay - what's the reasoning behind all this? I'd like to know... sincerely-
thus my OP here seeking clarification.

I mean, that advice can't be taken as "automatically good" simply because it
was written down somewhere. It's not like we're dealing with self-evident
truths. Imagine how thoroughly useless Framework Design Guidelines would
have been if no explanations and narrative were given.... okay I'll stop
(crappy documentation is a pet peve of mine).

IMHO, the biggest reason to use events is if you're doing to have multiple
subscribers. I don't find the IAsyncResult pattern all that unwieldy,
especially from the client side of things. And if you are, as MSDN
suggests, going to implement the underlying async behavior using an
IAsyncResult-like architecture anyway, it seems like exposing it would be
fine.

But events are IMHO slightly simpler to grasp at first, they are more
consistent with the bulk of the Forms-related API, and they do allow for
multiple subscribers with respect to async operations, even if one often
would not need that functionality.

On the other hand, if your design wants to ensure only one method at most
will receive notification of the end of an async operation, you would
probably want to stay away from the event-based model.

The biggest disconnect I have is the implication that I would be
implementing an async pattern based on an IAsyncResult in the first place,
as well as the statement that "it is rare" to see IAsyncResult without a
parallel event pattern. I can't explain why they would write that, since
I can think of plenty of counter-examples to both ideas.

Thanks for the thoughtful response. This is helpful discussion.

Which is better? It depends.

Sorry, you asked for it. :)

LOL! I somehow knew that was coming.

Thanks for getting past my 'tude in the OP.

I'm still wondering why Cwalina et al didn't mention the event patternat all
in the Framework Design Guidelines book IF it's as important as the above
MSDN article at the above link suggests. Maybe the .NET framework authors
haven't yet read the article :)

-Frankie
 
P

Peter Duniho

Frankie said:
[...]
Okay, fair enough on the "tone" part of my OP. But back to the MSDN doc...
they are very explicit about their recommendations yet give little or no
explanation. Recommendations usually come with explanation.

Well, they should. I would definitely agree that there are numerous
examples in MSDN of recommended practices that don't do a good job of
justifying those practices.

IMHO in many cases the recommendations are spot-on, but I also think the
docs are missing a great opportunity to educate when they don't
elaborate on the "why" aspect.

Sadly, I've found MSDN to actually be quite good compared to the
programming API docs I've found for other systems. To some extent, the
issue is simply that documenting something as large as an operating
system or framework that is similar to an operating system is a
monumental task.

One of the most helpful things you can do when you come across stuff
like this is to use the Feedback link to report the page as being
lacking. Provide a detailed comment about what exactly you think could
be improved. No guarantees, but I'll bet the squeaky wheel will get the
grease. :)
The following
aren't very enlightening (from the above link):
<quote>
Do not expose the IAsyncResult pattern without also exposing the
event-based pattern.
</quote>
then
<quote>
If you must expose both the event-based pattern and IAsyncResult pattern
on a single calss, use the EditorBrowsableAttribute set to Advanced to mark
the IAsyncResult pattern implementation as an advanced feature... blah blah
blah
</quote>

Okay - what's the reasoning behind all this? I'd like to know... sincerely-
thus my OP here seeking clarification.

Well, those comments suggest to me that their primary motivation behind
suggesting that the event-based model is better is its simplicity. And
IMHO it is that. .NET programmers _must_ be familiar with using events.
It's too integral to the way .NET works. So, it should be a simple
matter for a programmer to use an event-based async model.

I think one could argue that multi-threaded, asynchronous code is not
for beginners, and thus allowing easy access via events is just asking
for trouble. That line of thinking would support an argument that the
IAsyncResult model is actually better, because it imposes a slightly
higher barrier, which should hopefully reduce the number of unqualified
programmers attempting to use it.

However, a) my experience has been that high barriers don't prevent
unqualified programmers from getting their hands dirty, they just make
the mess worse when those programmers do get into it, and b) the
BackgroundWorker class seems to me to be a great example of how simple
an asynchronous API can be.

Granted, I think most event-based asynchronous models don't go to the
trouble of what BackgroundWorker does. In particular, I'm not aware of
any consistent .NET design goal that stipulates that the events are
always raised on the appropriate thread. Yes, the Forms-based stuff has
the Timer class, and the BackgroundWorker of course, but more generally
I don't see a lot of enforcing of where the events are raised.

But they could, and IMHO if it's reasonably simple to build that in,
they should.

Of course, now that I'm writing this, I realize that I really wish I
knew more about exactly how BackgroundWorker does what it does. :) I
don't actually know the specifics, even though I can think of at least a
couple of different ways it could implement that. IMHO it would be nice
if the docs could include a discussion of techniques similar to what
BackgroundWorker does, so that when we design classes we can build in
similar features.
[...]
I'm still wondering why Cwalina et al didn't mention the event patternat all
in the Framework Design Guidelines book IF it's as important as the above
MSDN article at the above link suggests. Maybe the .NET framework authors
haven't yet read the article :)

I don't know. I don't know anything about the book at all, never mind
its relationship to the current .NET. It may be that when it was
written, the event-based models weren't considered "better", or even
appropriate for async programming (in the Forms namespace they are
mostly used as a layer above the window message system, which is all
essentially single-threaded).

Times change. :)

Pete
 
F

Frankie

Thanks Peter for your opinions and commentary. It is helpful to get the
additional perspective.

[...]
I'm still wondering why Cwalina et al didn't mention the event patternat
all in the Framework Design Guidelines book IF it's as important as the
above MSDN article at the above link suggests. Maybe the .NET framework
authors haven't yet read the article :)

I don't know. I don't know anything about the book at all, never mind its
relationship to the current .NET. It may be that when it was written, the
event-based models weren't considered "better", or even appropriate for
async programming (in the Forms namespace they are mostly used as a layer
above the window message system, which is all essentially
single-threaded).

Times change. :)


Framework Design Guidelines was published in September 2005, so it's fairly
current, covering generics and other .NET 2.0 fundamentals. Here's a
shrunken link to the book at Amazon.com: (http://tinyurl.com/33zkv3)...

IMHO it's an excellent book because:
1. it comes from the guys "at ground zero" of .NET Framework development.
2. It is full of categorized recommendations (Do..., Consider..., Avoid...,
and Do Not...- all in the form of concise bullet points).
3. It gives a unique insight into the rationalle behind the decisions that
went into creating the .NET Framework.
4. It serves as a handy reference in that it can be understood as a big list
of categorized recommendations. So next time you're designing an Exception
handling strategy for a new application you can review chapter 7, or one of
its subsections relevant to whatever you may be uncertain about.

This is a rather unique book in that it presents as a formal textbook
presentation of the subject, yet the formal treatment is frequently
interrupted with casual narrative, opinions, anecdotes, and tips. Have you
ever thought that System.IO was unintuitive? Me too. Want to know why? This
book gives some insight into how it got that way and lessons learned (page
17-18).

From another perspective, I view this book as having a similar intent as
Steve McConnell's Code Complete (in that it presents best codign
practices) - but targeted specifically at .NET development.

Later...

Frankie
 
P

Peter Duniho

Frankie said:
Framework Design Guidelines was published in September 2005, so it's fairly
current, covering generics and other .NET 2.0 fundamentals.

Well, when did they _start_ writing it? Just because it was published
in 2005, that doesn't mean they started writing it in 2005.

I obviously don't have any useful insight as to why the book differs
from MSDN on these points. I don't know why it would leave out the
question of an event-based async pattern. There are a number of
possible explanations though, very few of which IMHO would ultimately
lead to a decisive conclusion one way or the other of which is "best".

Personally, I see very little difference between using IAsyncResult
directly and having an event-based pattern. The one thing IAsyncResult
does provide is a three-option mechanism; in addition to using a
callback, you can either poll a flag or wait on a handle. However, a)
IMHO neither of those techniques is generally preferred over a callback,
and b) one could easily implement either of those techniques given a
callback.

This line of thinking also applies to the "one callback only" versus
"multicast callback" difference between IAsyncResult/callback and an
event-based paradigm. You can easily implement a true event-based
paradigm layered on top of a single callback, so even that one minor
difference doesn't seem to really be a legitimate reason for doing one
over the other. Which ever design pattern you choose, you cannot
actually prevent the client code from doing whatever they want with it.

And since an event-based paradigm is in many ways essentially the same
as a callback, it's my opinion that which you choose has very little
real effect on the overall architecture of a program. That is, some
design decisions lead to very specific implementation details in other
areas. They are critical to the outcome of the program, and if they are
made incorrectly you will either need to go back and rewrite the
affected code or you will live with some serious headaches for a long
time. But I just don't see that sort of thing happening with respect to
event versus IAsyncResult decision-making.

IMHO, the event-based paradigm is a little cleaner, but the
IAsyncResult/callback mechanism hasn't ever really seemed overly
complicated either. I think to some extent it may depend mostly on what
you expect will be the most common use of your async pattern, and try to
design to that. If the typical use will be strictly callback-oriented,
an event-based paradigm may be preferable, but if you expect the client
to be doing their own waiting and/or polling the state flag (yuck),
IAsyncResult could be preferred.

And, for all of that, I think it's possible that what's really happened
is that originally it was all IAsyncResult and then somewhere along the
line the light-bulb turned on in some .NET architect's head and they
realized that this event paradigm that they already had for other stuff
would work great for an async API.

Of course, all of this is pure speculation on my part. I have zero
personal insight as to what drives the .NET design. For what it's
worth, when I have seen these questions answered, it has almost always
been in the context of a blog written by some .NET team member, or on
the MSDN web forums. You may have some success posting a similar
question there, in case someone who actually wrote the code or the
documentation sees it and can answer it directly.

Some times someone here will either already have seen such an answer, or
will have some personal contact with the person who really knows, but it
appears that's not the case at this point. Or at least, if it is,
you'll have to wait until after Labor Day to find out. :)

Pete
 

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

Top