如何等待网络流有数据可供读取?

发布于 2024-08-03 17:43:26 字数 544 浏览 3 评论 0原文

我的应用程序中有一个工作线程负责三件不同的事情。对其中两个作业的请求出现在我编写的队列中,当网络流上出现请求时,另一个作业就会被激活。我希望我的工作线程在没有工作要做时等待。这对于两个队列来说很容易,因为它们公开了一个 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 吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

因为看清所以看轻 2024-08-10 17:43:26

您可以使用 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
    }
}

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
    }
}
笛声青案梦长安 2024-08-10 17:43:26

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

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

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

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.

如果没有 2024-08-10 17:43:26

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

networkstream.Read(buffer, 0, 0);

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文