From: Julie on
So, I currently have code for reading in TCP/IP messages that looks
something like this:

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

This is one thread in my application, and as it is a non-blocking
infinite loop, it is causing my application to consume 100% of my
CPU.

Is there a simple method of rewriting this to cause it to block when
there's nothing else to read? (thereby freeing up CPU)

I attempted to use StreamReader.ReadBlock(), but then realized that
this really doesn't block when the stream is empty either.

Thanks!
From: Andrew Poelstra on
On 2010-01-21, Julie <julievogelman0(a)gmail.com> wrote:
> So, I currently have code for reading in TCP/IP messages that looks
> something like this:
>
> StreamReader reader = new StreamReader(new NetworkStream(mySocket)));
> while (true)
> {
> string inputString = reader.ReadLine();
> _newMessages.Enqueue(inputString);
> }
>
> This is one thread in my application, and as it is a non-blocking
> infinite loop, it is causing my application to consume 100% of my
> CPU.
>
> Is there a simple method of rewriting this to cause it to block when
> there's nothing else to read? (thereby freeing up CPU)
>
> I attempted to use StreamReader.ReadBlock(), but then realized that
> this really doesn't block when the stream is empty either.
>
> Thanks!

You can create (a single) thread and use Thread.Sleep(). This also
lets you expand to allow multiple connections easily.

From: Peter Duniho on
Julie wrote:
> So, I currently have code for reading in TCP/IP messages that looks
> something like this:
>
> StreamReader reader = new StreamReader(new NetworkStream(mySocket)));
> while (true)
> {
> string inputString = reader.ReadLine();
> _newMessages.Enqueue(inputString);
> }
>
> This is one thread in my application, and as it is a non-blocking
> infinite loop, it is causing my application to consume 100% of my
> CPU.

That doesn't make sense. StreamReader.ReadLine() blocks until input is
available from the underlying Stream, which in turn should block until
input is available. It doesn't poll the socket (or at least, it should
not�my experience is that it does not).

> Is there a simple method of rewriting this to cause it to block when
> there's nothing else to read? (thereby freeing up CPU)
>
> I attempted to use StreamReader.ReadBlock(), but then realized that
> this really doesn't block when the stream is empty either.

You should post a concise-but-complete code example that demonstrates
the 100% CPU usage. I suspect that the problem is not in the code
you've shown, as StreamReader should be using the NetworkStream in a
blocking manner.

Pete
From: Peter Duniho on
Andrew Poelstra wrote:
> You can create (a single) thread and use Thread.Sleep(). This also
> lets you expand to allow multiple connections easily.

The Thread.Sleep() method is primarily for when a thread knows it has a
specific length of time it has to sleep. It can be used for yielding,
but that's almost always incorrect design.

In this particular example, there's nothing in the code posted to
suggest the thread isn't blocking correctly already, and all that
calling Thread.Sleep() will do is slow that thread down. Sure, it'll
use less CPU, but it'll do less work over a given amount of time too.

Pete
From: Andrew Poelstra on
On 2010-01-22, Peter Duniho <no.peted.spam(a)no.nwlink.spam.com> wrote:
> Andrew Poelstra wrote:
>> You can create (a single) thread and use Thread.Sleep(). This also
>> lets you expand to allow multiple connections easily.
>
> The Thread.Sleep() method is primarily for when a thread knows it has a
> specific length of time it has to sleep. It can be used for yielding,
> but that's almost always incorrect design.
>
> In this particular example, there's nothing in the code posted to
> suggest the thread isn't blocking correctly already, and all that
> calling Thread.Sleep() will do is slow that thread down. Sure, it'll
> use less CPU, but it'll do less work over a given amount of time too.
>
> Pete

The code looked okay, but the OP claimed that it was spinning the CPU
and that a delay would be nice.

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.