9

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

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

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

有谁知道当 NetworkStream 有数据时设置 WaitHandle 的方法?

4

3 回答 3

7

您可以使用 NetworkStream 的异步方法并在 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
    }
}
于 2009-09-01T19:02:27.130 回答
2

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

或者,您可以使用异步 IO,但这有点棘手 - 而且您仍然需要一些额外的队列。

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

于 2009-09-01T10:44:00.213 回答
0

我发现,如果你NetworkStream.Read用调用size = 0,它实际上会阻塞:

networkstream.Read(buffer, 0, 0);

文档对此并不清楚,但对我来说它有效。

于 2019-08-20T11:43:37.063 回答