Re: Async TCPClients
- From: "Shak" <me@xxxxxxxxxxx>
- Date: Tue, 20 Jun 2006 10:12:22 +0100
"Dave Sexton" <dave@jwa[remove.this]online.com> wrote in message
news:OeNG0D9kGHA.5072@xxxxxxxxxxxxxxxxxxxxxxx
Hi Shak,
Inline:
If you are worried about blocking a ThreadPool thread then spawn your
own Thread and use synchronous NetworkStream calls.
But I wouldn't worry about it anyway. Just don't call EndRead while on
a ThreadPool thread because nested ThreadPool calling may cause a
deadlock. i.e. don't execute asynchronously on a ThreadPool thread to
make another asynchronous call on another ThreadPool thread (this may
cause a dead-lock).
Do you mean NOT to use the Async callback to reestablish the async?
Actually, I should have written "don't call Begin*" while on a ThreadPool
Thread since it is the Begin* methods that spawn a ThreadPool Thread, not
the End* methods. The reason you shouldn't call into an asynchronous
method from an asynchronous method where both threads will use the
ThreadPool is that it can cause dead-locks because there is a limit to the
number of ThreadPool Threads provided to your application (related to the
number of physical processors). However, for a simple RPC app, especially
if there will be a limited number of client connections, it is acceptable
to call BeginAsync from the AsyncCallback.
I think that's how I had read it anyway! I do understand the danger here,
but if the re-call to Begin* is the last thing done in the callback (ie the
callback has no more oppurtunity to block) then wouldn't it be ok, even in
the worst case? I think I'll have no more than a handful of clients anyway,
but I'll think about moving to a loop I ever need to scale it up.
Your point 3 in the RPC method below suggests I should loop with a
synchronous method instead of calling BeginAsync again.
If you were to use a synchronous loop you could spawn your own Thread
using a ThreadStart object to prevent dead-locks, but there may be a
slight performance cost. I have not compared the two methods. A problem
that you must work out when using a synchronous loop is that one client
should not have to wait for another client's RPC to complete before it can
establish a connection, so some asynchronous code is still required.
Preferably, code not executing on a ThreadPool Thread.
Hmm. But if a socket has already been established (and has it's own thread
on which it is reading on), surely it wouldn't matter? Going back to my
Async model:
//somewhere else
o.BeginAsync(completeAsync, o)
....
void completeAsync(IAsyncResult ar)
{
Class o = (Class)ar.SyncState;
o.EndAsync();
//do stuff for this async cycle
//resestablish wait
o.BeginAsync(completeAsync, o)
}
This is as opposed to a sync loop:
//somewhere else
StartAThread(o.Work) //(1)
....
void Work()
{
while (true)
{
o.Begin(); // blocks
//do stuff for this cycle.
}
}
Where (1) can be replaced by your thread-kicking-off code of choice.
Presumeably for the TCPClient connecting case, "do stuff for this cycle"
means to establish a further thread to poll on read (either via async or
kicking off another thread manually). I don't think either introduce the
possibility of deadlock, although I'm now seeing the latter as being more
efficient since it doesn't create new threads. Do both these models fulfill
your condition that "one client should not have to wait for another client's
RPC to complete before it can establish a connection", though?
It seems that most Async calls (especially in streams and the like) seem to
be for a job that repeats. If this is the case, and a loop that blocks is
more efficient, what's the point of having Async calls? I mean it's not like
you'll only want to read or write to a stream once, right?
OK. I do have another question though: What happens if, while reading
bytes off of a network stream more data gets sent? Abstracting away from
the above, say you are expecting a particular message of unknown length.
How do you know when to stop reading bytes? All the examples I've seen
seem to wait till the number of bytes read<=0. Couldn't we get more than
one message accedentally in that scenario? If at all it stops?
A few things here...
That's brilliant, and exactly as I imagined it to be. In short, you have to
be able to determine when what you're receiving ends, usually using some
kind of prefix or suffix. Cool!
Shak
.
- Follow-Ups:
- Re: Async TCPClients
- From: Dave Sexton
- Re: Async TCPClients
- References:
- Async TCPClients
- From: Shak
- Re: Async TCPClients
- From: Dave Sexton
- Re: Async TCPClients
- From: Shak
- Re: Async TCPClients
- From: Dave Sexton
- Async TCPClients
- Prev by Date: VB Express vs. ????
- Next by Date: live chat application
- Previous by thread: Re: Async TCPClients
- Next by thread: Re: Async TCPClients
- Index(es):
Relevant Pages
|