4 way of Asynchronous Programming, what is the differenen between the first two?

R

Ryan Liu

Hi,

I read Microsoft SDK,
ms-help://MS.NETFrameworkSDKv1.1/cpguidenf/html/cpovrasynchronousprogramming
overview.htm

there are 4 ways to call EndInvoke:

The code in this topic demonstrates four common ways to use BeginInvoke and
EndInvoke to make asynchronous calls. After calling BeginInvoke you can:

a.. Do some work and then call EndInvoke to block until the call
completes.
b.. Obtain a WaitHandle using IAsyncResult.AsyncWaitHandle, use its
WaitOne method to block execution until the WaitHandle is signaled, and then
call EndInvoke.
c.. Poll the IAsyncResult returned by BeginInvoke to determine when the
asynchronous call has completed, and then call EndInvoke.
d.. Pass a delegate for a callback method to BeginInvoke. The method is
executed on a ThreadPool thread when the asynchronous call completes, and
can call EndInvoke.

What is the difference between the first two way since EndInvoke itself will
block anyway?

BTW, in the second case, will EndInvoke block anymore?

Thanks!
Ryan
 
W

William Stacey [C# MVP]

They are close, but slightly different. The first will call WaitOne on the
handle if not already complete. If it is complete, it will not create the
waithandle which can be more efficent. The second one will always create
the waithandle (i.e. a resetevent) whether the thing is complete or not.
The second would also allow you to wait on other events (i.e. WaitAny, etc)
because you have the handle. Unless you need to "gather" other async
events, the 4th one is recommended as your only called when it is complete
and you also avoid creating the waithandle (and IMO, seems the most
natural). On a busy server, for example, that can add up to some real
savings.

--
William Stacey [C# MVP]

| Hi,
|
| I read Microsoft SDK,
|
ms-help://MS.NETFrameworkSDKv1.1/cpguidenf/html/cpovrasynchronousprogramming
| overview.htm
|
| there are 4 ways to call EndInvoke:
|
| The code in this topic demonstrates four common ways to use BeginInvoke
and
| EndInvoke to make asynchronous calls. After calling BeginInvoke you can:
|
| a.. Do some work and then call EndInvoke to block until the call
| completes.
| b.. Obtain a WaitHandle using IAsyncResult.AsyncWaitHandle, use its
| WaitOne method to block execution until the WaitHandle is signaled, and
then
| call EndInvoke.
| c.. Poll the IAsyncResult returned by BeginInvoke to determine when the
| asynchronous call has completed, and then call EndInvoke.
| d.. Pass a delegate for a callback method to BeginInvoke. The method is
| executed on a ThreadPool thread when the asynchronous call completes, and
| can call EndInvoke.
|
| What is the difference between the first two way since EndInvoke itself
will
| block anyway?
|
| BTW, in the second case, will EndInvoke block anymore?
|
| Thanks!
| Ryan
|
|
 
R

Ryan Liu

William Stacey said:
They are close, but slightly different. The first will call WaitOne on the
handle if not already complete. If it is complete, it will not create the
waithandle which can be more efficent. The second one will always create
the waithandle (i.e. a resetevent) whether the thing is complete or not.
The second would also allow you to wait on other events (i.e. WaitAny, etc)
because you have the handle. Unless you need to "gather" other async
events, the 4th one is recommended as your only called when it is complete
and you also avoid creating the waithandle (and IMO, seems the most
natural). On a busy server, for example, that can add up to some real
savings.

--
William Stacey [C# MVP]

| Hi,
|
| I read Microsoft SDK,
|
ms-help://MS.NETFrameworkSDKv1.1/cpguidenf/html/cpovrasynchronousprogramming
| overview.htm
|
| there are 4 ways to call EndInvoke:
|
| The code in this topic demonstrates four common ways to use BeginInvoke
and
| EndInvoke to make asynchronous calls. After calling BeginInvoke you can:
|
| a.. Do some work and then call EndInvoke to block until the call
| completes.
| b.. Obtain a WaitHandle using IAsyncResult.AsyncWaitHandle, use its
| WaitOne method to block execution until the WaitHandle is signaled, and
then
| call EndInvoke.
| c.. Poll the IAsyncResult returned by BeginInvoke to determine when the
| asynchronous call has completed, and then call EndInvoke.
| d.. Pass a delegate for a callback method to BeginInvoke. The method is
| executed on a ThreadPool thread when the asynchronous call completes, and
| can call EndInvoke.
|
| What is the difference between the first two way since EndInvoke itself
will
| block anyway?
|
| BTW, in the second case, will EndInvoke block anymore?
|
| Thanks!
| Ryan
|
|


When we talking about server saving, I have some concerns.

Whew I use async I/O methods, is try to reduce thread I am using in a C/S
application ( I use one thread per client).

But BeginXxx method will use a thread, then my reducing thread intention
will go vain?

Thanks a lot!
 
C

Chris Mullins

Ryan Liu said:
Whew I use async I/O methods, is try to reduce thread I am using in a C/S
application ( I use one thread per client).

But BeginXxx method will use a thread, then my reducing thread intention
will go vain?

The Begin/End methods don't use threads in the same sense that your "1
thread per client" uses threads. They instead leverage an IO Completion Port
and give you an efficient thread scheduling mechanism.

For some analysis of building a (very) big socket server, see a blog entry I
did a while back:
http://www.coversant.net/Default.aspx?tabid=88&EntryID=10
 
W

William Stacey [C# MVP]

| In the second case, EndInvoke is not asynchronous so it technically
"blocks"
| but it doesn't wait on anything and simply returns your result.

IIRC, the EndInvoke will not block or even call waitone, because the result
is already complete (so it skips that step and returns result).
--wjs
 
R

Ryan Liu

Hi Chirs,

Thanks a lot for your reply and article.

First, a basic general question, when will the callback method be called?
Right after BeginReceive() or when the data is available? It shoulb be
called in the same thread which receives data and is called after data is
available, right?

Is that possible to show a few lines sample to demonstrate your idea?

For stage 3:

Is that(if not, what about)per Processing Queue per client/socket?

And where we put the IAsncResult in the queue? From stage 3 diagram, seems
this is done inside BeginReceiveCallBack method. What about we put it into
queue by code immediate follow socket.BeginReceive().

Between the EndRecevie BeginReceive, the socket is not receiving data (if
socket buffer is full) and could block client. Is this the same case for
stage 2 and 3? So the stage 3 does not solve one of the problem stage 2 has?


So is that better to take processing time out of time between EndReceive and
BeginReceive? That is call BeginReceive right after put IAsncResult in the
queue, instead call it at the end of process.


And clients send different kind of message and vary in size, when I call
BeginReceive, how can I specify the size? How can I make sure I won't get
into the middle of message, e.g. get 1.5 message in byte[]?

BeginReceive will use thread in thread pool. And for threads that processing
queue, are explicitly created by our code, right?

But if as I said, call BeginReceive right after put IAsncResult in the
queue, then we never explicitly create any threads and we seems call
BeginReceive more frequently and use more threads in thread pool. Is this
right statement?

Thanks a lot!
Ryan
 

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