How do you wait for a Network Stream to have data to read?

妖精的绣舞 提交于 2019-12-18 16:47:06

问题


I have a worker thread in my application that is responsible for three different things. Requests for two of the jobs turn up in Queues that I have written, the other job is activated when a request turns up on a Network stream. I would like my worker thread to wait when there is no work to be done. This is easy with the two Queues as they expose a ManualResetEvent that is set when they have items, however the NetworkStream does not seem to have this. The NetworkStream has been retrieved from a TcpClient.

What I am after is code that looks something like this:

while (notDone)
{
    WaitHandle.WaitAny(new WaitHandle[] { queue1.HasData, queue2.HasData, netStream.HasData } );
    // ...
    if (netStream.DataAvailable)
    {
        netStream.Read(buffer, 0, 20);
        // process buffer
    }
}

Does anyone know a way to get a WaitHandle that is set when a NetworkStream has data?


回答1:


You can use the async methods of the NetworkStream and set a ManualResetEvent in the EndReceive method.

// ...
netStream.BeginRead(buffer, offset, callback, state);
// ...

inside the callback method

netStream.EndRead(ar);
netStreamManualResetEvent.Set();

then your code

while (notDone)
{
    WaitHandle.WaitAny(new WaitHandle[] { queue1.HasData, queue2.HasData, netStreamManualResetEvent} );
    // ...
    if (netStream.DataAvailable)
    {
        // make the buffer from the AsyncState in the callback method available here
        // process buffer
    }
}



回答2:


The simplest way is probably to use an additional thread which reads synchronously and puts extra data onto an extra queue.

Alternatively you could use asynchronous IO, but that's somewhat tricky - and you'd still need to have some additional queue.

Although Socket has a Select() method (and you can get at a socket from a NetworkStream) I don't believe it exposes this functionality in a way which lets you mix it with other kinds of wait handles.




回答3:


I discovered, that if you call NetworkStream.Read with size = 0, it will actually block:

networkstream.Read(buffer, 0, 0);

The documentation is not clear about this, but for me it worked.



来源:https://stackoverflow.com/questions/1361714/how-do-you-wait-for-a-network-stream-to-have-data-to-read

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!