你如何等待网络流来读取数据?

时间:2009-09-01 10:29:46

标签: c# multithreading networkstream

我的应用程序中有一个工作线程,它负责三个不同的事情。在我编写的队列中,有两个作业的请求出现,另一个作业在网络流上出现请求时被激活。我希望我的工作线程在没有工作要做的时候等待。这两个队列很容易,因为它们暴露了一个在有​​项目时设置的ManualResetEvent,但是NetworkStream似乎没有这个。已从TcpClient检索NetworkStream。

我所追求的是看起来像这样的代码:

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

有人知道获取NetworkStream有数据时设置的WaitHandle的方法吗?

3 个答案:

答案 0 :(得分:7)

您可以使用NetworkStream的async方法,并在EndReceive方法中设置ManualResetEvent。

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

在回调方法中

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

然后你的代码

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
    }
}

答案 1 :(得分:2)

最简单的方法可能是使用另一个同步读取并将额外数据放入额外队列的线程。

或者你可以使用异步IO,但这有点棘手 - 你还需要一些额外的队列。

虽然Socket有一个Select()方法(并且您可以从NetworkStream获取套接字),但我不相信它会以一种让您混合它的方式公开此功能与其他类型的等待句柄。

答案 2 :(得分:0)

我发现,如果您用NetworkStream.Read调用size = 0,它将实际上阻止:

networkstream.Read(buffer, 0, 0);

documentation尚不清楚,但对我来说确实有用。