Regarding your original question, John, I think that queueing EndWebService
in the threadpool is wrong.  The server code should never call End*, either
directly or indirectly (e.g. through the thread pool).  If you (as the
client) register a completion callback, the framework will always call it,
regardless of whether the operation threw an exception, ran to completion
or was cancelled in the middle (actually, there's no way for the framework
to distinguish between the latter two cases).  The callback method is the
correct place to call End*.

Regarding the two asynchronous programming patterns, this is what the MSDN
library has to say:

“The IAsyncResult design pattern allows for a variety of programming
models, but is more complex to learn and provides a flexibility that most
applications do not require. Where possible, class library designers should
implement asynchronous methods using the event-driven model. In some cases
the library designer should also implement the IAsyncResult based model.”

The event-based pattern does not supersede the IAsyncResult-based pattern,
which is still the only way to work with asynchronous delegates and to
invoke WCF services asynchronously.  I think the event-based pattern was
designed to address the relative difficulty of implementing the
IAsyncResult-based pattern correctly, since when you implement an
IAsyncResult-based asynchronous operation, you need to test it with four
different kinds of application code: polling for completion, waiting for
completion, blocking until completion, and using a completion callback.

Ron


"Discussion of advanced .NET topics." <ADVANCED-DOTNET@DISCUSS.DEVELOP.COM>
wrote on 16/08/2007 07:00:11:

> There are 4 messages totalling 185 lines in this issue.
>
> Topics of the day:
>
>   1. Canceling an asynchronous method call (3)
>   2. Stateless, static data access layer
>
> ===================================
> This list is hosted by DevelopMentor®  http://www.develop.com
>
> View archives and manage your subscription(s) at
http://discuss.develop.com
>
> ----------------------------------------------------------------------
>
> Date:    Wed, 15 Aug 2007 09:48:55 -0500
> From:    John Bush <[EMAIL PROTECTED]>
> Subject: Canceling an asynchronous method call
>
> When using Begin/End methods to asynchronously invoke a method, my
> understanding is that you always need to call the End method or
> resources will be leaked.
>
> But let's say I'm calling a web service and want the user to be able
> to cancel it:
>
> IAsyncResult result = proxy.BeginWebService(...);
>
> while (!result.IsCompleted)
> {
>   Thread.Sleep(500);
>
>   if (backgroundWorker.CancellationPending)
>   {
>     // we need to make sure EndWebService gets called
>     ThreadPool.QueueUserWorkItem(delegate { proxy.EndWebService(result);
});
>     return;
>   }
> }
>
> proxy.EndWebService(result);
>
> Would that be the correct way to go about it? If the user wants to
> cancel, I need to bail out of the loop, but I also need to make sure
> EndWebService gets called. I don't want to make the user wait for the
> web service call to complete, so is it ok to have the thread pool make
> the EndWebService call?
>
> -John
>
> ===================================
> This list is hosted by DevelopMentor®  http://www.develop.com
>
> View archives and manage your subscription(s) at
http://discuss.develop.com
>
> ------------------------------
>
> Date:    Wed, 15 Aug 2007 13:29:35 -0400
> From:    Peter Ritchie
<[EMAIL PROTECTED]>
> Subject: Re: Canceling an asynchronous method call
>
> How are you implementing BeginWebService?  By default Visual Studio
> generates *Async methods to execute web service methods asynchronously,
> which is then "ended" via the call to the callback.  An asynchronous call
> can be canceled via the CancelAsync method.
>
> -- Peter
>
> On Wed, 15 Aug 2007 09:48:55 -0500, John Bush <[EMAIL PROTECTED]> wrote:
>
> >When using Begin/End methods to asynchronously invoke a method, my
> >understanding is that you always need to call the End method or
> >resources will be leaked.
> >
> >But let's say I'm calling a web service and want the user to be able
> >to cancel it:
> >
> >IAsyncResult result = proxy.BeginWebService(...);
> >
> >while (!result.IsCompleted)
> >{
> >  Thread.Sleep(500);
> >
> >  if (backgroundWorker.CancellationPending)
> >  {
> >    // we need to make sure EndWebService gets called
> >    ThreadPool.QueueUserWorkItem(delegate { proxy.EndWebService
> (result); });
> >    return;
> >  }
> >}
> >
> >proxy.EndWebService(result);
> >
> >Would that be the correct way to go about it? If the user wants to
> >cancel, I need to bail out of the loop, but I also need to make sure
> >EndWebService gets called. I don't want to make the user wait for the
> >web service call to complete, so is it ok to have the thread pool make
> >the EndWebService call?
>
> ===================================
> This list is hosted by DevelopMentor®  http://www.develop.com
>
> View archives and manage your subscription(s) at
http://discuss.develop.com
>
> ------------------------------
>
> Date:    Thu, 16 Aug 2007 00:25:29 +0100
> From:    Barry Kelly <[EMAIL PROTECTED]>
> Subject: Re: Canceling an asynchronous method call
>
> John Bush <[EMAIL PROTECTED]> wrote:
>
> > When using Begin/End methods to asynchronously invoke a method, my
> > understanding is that you always need to call the End method or
> > resources will be leaked.
>
> To make life easy, I always call the End method in a callback, passed to
> the Begin half of the method. Basically, programming in a manually
> written continuation passing style (CPS:
> http://en.wikipedia.org/wiki/Continuation_passing_style). React in the
> continuation as you will - basically, return or whatever after you've
> called the *End method.
>
> =46WIW, I detest and abhor the newer "easy" *Async methods that use
> stateful, non-functional style events rather than callbacks - I find it
> makes writing asynchronous code far harder.
>
> -- Barry
>
> --=20
> http://barrkel.blogspot.com/
>
>
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

> This list is hosted by DevelopMentor=AE  http://www.develop.com
>
> View archives and manage your subscription(s) at
http://discuss.develop.com
>
> ------------------------------
>
> Date:    Wed, 15 Aug 2007 18:40:08 -0500
> From:    Ron Young <[EMAIL PROTECTED]>
> Subject: Re: Stateless, static data access layer
>
> Thanks for that info. Actually made me see that whole layer differently,
=
> thinking about interface DAL, instance DAL classes.
>
> Testing with NMock or later would definitely be nice to have.
>
> -----Original Message-----
> From: Discussion of advanced .NET topics. =
> [mailto:[EMAIL PROTECTED] On Behalf Of Brad Wilson
> Sent: Tuesday, August 14, 2007 8:01 PM
> To: ADVANCED-DOTNET@DISCUSS.DEVELOP.COM
> Subject: Re: [ADVANCED-DOTNET] Stateless, static data access layer
>
> I suppose that depends on whether or not you want to test your system
> without a database. If things are tightly coupled to static methods on a
> specific class, there is no opportunity to replace it with something =
> else
> for testing purposes (i.e., something that returns test data rather than
> talking to a database).
>
> On 8/14/07, Ron Young <[EMAIL PROTECTED]> wrote:
> >
> > Anything wrong with a DAL that is tightly coupled to stored procedures
=
> and
> > strongly typed datasets? If not then the first level of the DAL =
> contains
> > those tightly coupled DAL classes with basically CRUD operations.
> >
>
> --
> http://www.agileprogrammer.com/dotnetguy/
> http://www.flickr.com/photos/dotnetguy/
> http://www.last.fm/user/dotnetguy/
>
>
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> This list is hosted by DevelopMentor=EF=BF=BD  http://www.develop.com
>
> View archives and manage your subscription(s) at =
> http://discuss.develop.com
>
>
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

> This list is hosted by DevelopMentor=AE  http://www.develop.com
>
> View archives and manage your subscription(s) at
http://discuss.develop.com
>
> ------------------------------
>
> End of ADVANCED-DOTNET Digest - 14 Aug 2007 to 15 Aug 2007 (#2007-159)
> **********************************************************************


The information contained in this message may be confidential and legally
privileged. The message is intended solely for the addressee(s). If you are
not the intended recipient, you are hereby notified that any use,
forwarding, dissemination, or reproduction of this message is strictly
prohibited and may be unlawful. If you are not the intended recipient,
please contact the sender by return e-mail and destroy all copies of the
original message.

Reply via email to