From: Peter Duniho on
Andrew Poelstra wrote:
> The code looked okay, but the OP claimed that it was spinning the CPU

She did claim that.

> and that a delay would be nice.

I don't think she did claim that.

I agree that the code as shown looks fine. Hence, IMHO we should not be
suggesting changes to that. Instead, we should insist on seeing the
code that's _not_ fine before making specific suggestions.

> One project I did used Thread.Sleep() after some packets were sent
> deliberately to slow the computer down, and give the client time
> to process the request.

There are situations when it might be beneficial to throttle output.
For example, bandwidth restrictions on the recipient, or you'd like to
reduce network congestion when using UDP.

But those kinds of situations fall exactly into the category I described
as a valid use of Thread.Sleep(): you have a specific, known amount of
time for which it's important for the thread to delay.

There's no indication that the OP in this case would benefit from the
use of Thread.Sleep().

Pete
From: Julie on
Hey guys,

So sorry - I posted this and then completely forgot to check the
responses! Thanks for responding.

I would not like to sleep in this thread because it actually does need
to operate as quickly as possible to process all of the TCP/IP input.

I was able to narrow it down to this thread causing my CPU usage. The
CPU was at 100%, then I froze the thread, and the CPU went back down.

That's interesting, Peter, that you believe ReadLine does block when
there's no incoming TCP/IP.

The code I posted that I'm using wasn't actually complete. Here is the
actual:

StreamReader reader = new StreamReader(new NetworkStream(mySocket)));
while (true)
{
string inputString = reader.ReadLine();
if (inputString != null)
{
_newMessages.Enqueue(inputString);
}
}

So, I'm actually checking for null, and I find that if there is no
incoming message, ReadLine() does not block and instead returns null.

Peter, are you able to run this same thing and find that ReadLine()
will block when there are no new messages? I can try to provide more
code if that's helpful.

Thanks! (and I promise this time not to forget about my post. :o)


From: Peter Duniho on
Julie wrote:
> [...]
> The code I posted that I'm using wasn't actually complete. Here is the
> actual:
>
> StreamReader reader = new StreamReader(new NetworkStream(mySocket)));
> while (true)
> {
> string inputString = reader.ReadLine();
> if (inputString != null)
> {
> _newMessages.Enqueue(inputString);
> }
> }
>
> So, I'm actually checking for null, and I find that if there is no
> incoming message, ReadLine() does not block and instead returns null.

Ah. So it is possible in that loop for ReadLine() to return null.

ReadLine() returns null when you've reached the end of the stream. So,
basically your code causes the thread to go into an infinite loop once
reaching the end of the stream.

And yes, not only will that prevent your thread from ever getting any
further than that loop, but once reaching the end of the stream there is
nothing to restrict the execution of the thread, so CPU usage will hit 100%.

Without more context, it's not possible to know exactly what the right
thing to do is. But, given that the TCP connection can eventually be
closed, somehow you need to handle that appropriately.

That might be as simple as just exiting the thread when the return value
is null:

StreamReader reader = new StreamReader(new NetworkStream(mySocket));
string str;

while ((str = reader.ReadLine()) != null)
{
_newMessages.Enqueue(inputString);
}

But like I said, not possible to say for sure with the given information.

Pete
From: Peter Duniho on
Peter Duniho wrote:
> [...]
> StreamReader reader = new StreamReader(new NetworkStream(mySocket));
> string str;
>
> while ((str = reader.ReadLine()) != null)
> {
> _newMessages.Enqueue(inputString);
> }

Of course, the above only works if you use the same variable name for
the "string" variable everywhere. Should be "str" or "inputString"
only; mixing and matching won't compile. :)

Sorry for my sloppiness.

Pete
From: Julie on
On Jan 22, 12:37 pm, Peter Duniho <no.peted.s...(a)no.nwlink.spam.com>
wrote:
> Peter Duniho wrote:
> > [...]
> >  StreamReaderreader = newStreamReader(new NetworkStream(mySocket));
> >   string str;
>
> >   while ((str = reader.ReadLine()) != null)
> >   {
> >     _newMessages.Enqueue(inputString);
> >   }
>
> Of course, the above only works if you use the same variable name for
> the "string" variable everywhere.  Should be "str" or "inputString"
> only; mixing and matching won't compile.  :)
>
> Sorry for my sloppiness.
>
> Pete

But what if the client takes a break from sending but still has more
to send? I don't want to stop checking for messages, but I don't want
to use up CPU either. Hmm...