gpt4 book ai didi

c# - NetworkStream.Read() 和 NetworkStream.BeginRead() 之间的区别?

转载 作者:太空狗 更新时间:2023-10-29 18:15:29 26 4
gpt4 key购买 nike

我需要从 NetworkStream 中读取,它会随机发送数据,数据包的大小也会不断变化。我正在实现一个多线程应用程序,其中每个线程都有自己的流来读取。如果流中没有数据,应用程序应该一直等待数据到达。但是,如果服务器发送完数据并终止了 session ,那么它应该退出。

最初我使用 Read 方法从流中获取数据,但它用于阻塞线程并一直等待直到数据出现在流中。

MSDN 上的文档建议,

If no data is available for reading, the Read method returns 0. If the remote host shuts down the connection, and all available data has been received, the Read method completes immediately and return zero bytes.

但在我的例子中,我从未让 Read 方法返回 0 并正常退出。它只是无限期地等待。

在我的进一步调查中,我遇到了 BeginRead,它会在接收到数据后立即监视流并异步调用回调方法。我也尝试使用这种方法寻找各种实现,但是,我无法确定何时使用 BeginReadRead 更有用。

在我看来,BeginRead 具有异步调用的优点,不会阻塞当前线程。但是在我的应用程序中,我已经有一个单独的线程来读取和处理来自流的数据,所以这对我来说没有太大区别。

  • 谁能帮我理解等待和退出机制BeginRead 以及它与 Read 有何不同?

  • 实现所需功能的最佳方式是什么?

最佳答案

我使用 BeginRead,但使用 WaitHandle 继续阻塞线程:

byte[] readBuffer = new byte[32];
var asyncReader = stream.BeginRead(readBuffer, 0, readBuffer.Length,
null, null);

WaitHandle handle = asyncReader.AsyncWaitHandle;

// Give the reader 2seconds to respond with a value
bool completed = handle.WaitOne(2000, false);
if (completed)
{
int bytesRead = stream.EndRead(asyncReader);

StringBuilder message = new StringBuilder();
message.Append(Encoding.ASCII.GetString(readBuffer, 0, bytesRead));
}

基本上,它允许使用 WaitHandle 的异步读取超时,如果读取在设定时间内完成( >2000 在这种情况下)。

这是从我的一个 Windows Mobile 项目中复制和粘贴的完整流阅读代码:

private static bool GetResponse(NetworkStream stream, out string response)
{
byte[] readBuffer = new byte[32];
var asyncReader = stream.BeginRead(readBuffer, 0, readBuffer.Length, null, null);
WaitHandle handle = asyncReader.AsyncWaitHandle;

// Give the reader 2seconds to respond with a value
bool completed = handle.WaitOne(2000, false);
if (completed)
{
int bytesRead = stream.EndRead(asyncReader);

StringBuilder message = new StringBuilder();
message.Append(Encoding.ASCII.GetString(readBuffer, 0, bytesRead));

if (bytesRead == readBuffer.Length)
{
// There's possibly more than 32 bytes to read, so get the next
// section of the response
string continuedResponse;
if (GetResponse(stream, out continuedResponse))
{
message.Append(continuedResponse);
}
}

response = message.ToString();
return true;
}
else
{
int bytesRead = stream.EndRead(asyncReader);
if (bytesRead == 0)
{
// 0 bytes were returned, so the read has finished
response = string.Empty;
return true;
}
else
{
throw new TimeoutException(
"The device failed to read in an appropriate amount of time.");
}
}
}

关于c# - NetworkStream.Read() 和 NetworkStream.BeginRead() 之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4388771/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com