views:

353

answers:

2

In my C# application, I have a thread which basically continually reads from a TcpClient until told to stop. I use WaitHandles for this purpose, for example:

private ManualResetEvent stopping;

private void Receive()
{
    while (!this.stopping.WaitOne(10))
    {
        while (this.client.Available > 0)
        {
            // Read and process data
        }
    }
}

As you can see, I'm waiting for the thread to be told to stop. If it hasn't been, it reads all data from the TcpClient and loops.

The problem I have is the 10ms delay, which I'd rather not have. I could reduce it, but I'd prefer a solution where the program will pause until EITHER the thread is told to stop, or more data becomes available.

In effect, what I want is a WaitHandle which tells me when data is available on the TcpClient. That way, I can use WaitHandle.WaitAny. Is there any way I can do this, or can someone suggest an alternative approach?

This can't be a bodge as it needs to be a fairly performant -and- lightweight background process.

+2  A: 

You'll need to use the BeginRead method on the underlying NetworkStream. This will return a IAsyncResult which has a AsyncWaitHandle property. Now you create an array of WaitHandle's, stick the AsyncWaitHandle in [0], the ManualResetEvent in [1] and then call WaitHandle.WaitAny() with the array, and it will either return the index of the handle that is set, or WaitTimeout on time out.

Once you know it's the AsyncHandle that's set, you can use EndRead to complete the read, and get the data into your buffer.

The help for BeginRead says you need a callback function, but you can pass Null for this and code everything in your base function if you prefer.

Gareth Wilson
A: 

I can pass a null for the callback? I wasn't aware of that. I'll have a play with that today and report back. Thanks.

Barguast