I am new to this topic, and happened upon this thread while trying to make
sense of the MSDN sample code at:
ms- help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconNon-
blockingServerSocketExample.htm
(a VB version of this is available online at:
http://msdn2.microsoft.com/library/fx6588te(en- us,vs.80).aspx)
My question is really about that sample, but first, let me state my
understanding of what you are saying, so you can let me know whether I have
it right:
You are saying that BeginReceive is "on the caller's thread." Certainly, it
is invoked from the caller's thread (which perhaps is what you mean).
However, the documentation clearly states that "When your application calls
BeginReceive, the system will use a separate thread to execute the
specified callback method, and will block on EndReceive until the Socket
reads data or throws an exception." So, according to the documentation, the
*callback* method does *not* execute on the caller's thread, but rather on
a thread that is spawned by the BeginReceive method.
Now, when EndReceive is invoked, it "blocks" until at least some data has
been received by the client. I assume that means that if any data has been
received at all, even a single character, it will "release," returning that
data.
So, when you say that EndReceive is "on a thread pool thread," I'm guessing
that you mean the thread that was allocated when BeginReceive was called;
the same thread on which the callback function that invoked EndReceive is
running. Which means that EndReceive does not allocate any new thread of
its own; it is a synchronous function (so far as its caller is concerned)
that waits for input from the client, and returns as soon as any has been
received.
Apologies for the length of the preceding; hopefully all of the above is
correct. Assuming that it is, on to my question about the sample code:
Given that the initial BeginReceive operation spawns a new thread on which
ReadCallBack runs, why is it necessary for ReadCallBack to invoke
BeginReceive *again*, spawning yet another thread, just to pick up the next
portion of the input from the client (which could happen an indefinite
number of times)? Why not have a Socket function that can perform a
*synchronous* read from the client (i.e., Socket.Receive()), and invoke
that function within a loop to pick up the rest of the input? The main
thread will not be blocked, as it has already spawned a worker thread when
it called the BeginAccept function.
Now, I know that the documentation for Socket.Receive says that "The
Receive method will only read data that arrives from the remote host
established in the Connect or Accept method." So, does that mean it will
*not* read data from a host established in the *BeginAccept* method?
Because I don't see why you couldn't mix an asynchronously-spawned
connection (e.g., BeginAccept / EndAccept) with synchronously performed
reading (e.g., Receive).
Creating a new thread for each little fragment of input seems unnecessarily
expensive, given that each invocation of the ReadCallBack delegate is just
exiting after it calls BeginReceive.
Thanks in advance for any insights you might provide.
Carl
Yes, BeginReceive is on the caller's thread, EndReceive is on a thread pool
thread (more specificaly on a IOCP thread).
[quoted text clipped - 12 lines]
Yes, BeginReceive is on the caller's thread, EndReceive is on a thread pool
thread (more specificaly on a IOCP thread).
[quoted text clipped - 12 lines]