C# 从NetworkStream读取。ReadLine()与读入ByteArray哪个更好?

C# 从NetworkStream读取。ReadLine()与读入ByteArray哪个更好?,c#,.net,multithreading,stream,C#,.net,Multithreading,Stream,我正在使用TcpClient与以“\n”分隔字符串形式发送信息的服务器通信。数据流相当高,一旦设置了通道,流将始终具有可读取的信息。消息的大小可以不同 我现在的问题是,使用ReadLine()方法从流中读取消息是否更好,因为它们已经用“\n”分隔,还是建议读取一些固定大小的byteArray并使用Split(“\n”)或类似方法从中提取消息字符串?(是的,我确实理解,在某些情况下,字节数组只能获取消息的一部分,我们也必须为此实现逻辑。) 此处需要考虑的要点包括: 表演 数据丢失。如果客户端读取

我正在使用TcpClient与以“\n”分隔字符串形式发送信息的服务器通信。数据流相当高,一旦设置了通道,流将始终具有可读取的信息。消息的大小可以不同

我现在的问题是,使用ReadLine()方法从流中读取消息是否更好,因为它们已经用“\n”分隔,还是建议读取一些固定大小的byteArray并使用Split(“\n”)或类似方法从中提取消息字符串?(是的,我确实理解,在某些情况下,字节数组只能获取消息的一部分,我们也必须为此实现逻辑。)

此处需要考虑的要点包括:

  • 表演

  • 数据丢失。如果客户端读取数据的速度不如输入数据的速度快,是否会丢失一些数据

  • 多线程设置。如果此设置必须在多线程环境中实现,其中每个线程都有一个单独的通信通道,但是在客户端上共享相同的资源,该怎么办

如果性能是您最关心的问题,那么我更喜欢
Read
而不是
ReadLine
方法。I/O是一个程序可以做的较慢的事情之一,因此您希望通过预先读取尽可能多的数据来最小化I/O例程中的时间量

如果您使用的是TCP,数据丢失在这里并不是一个真正的问题。TCP协议保证传输,并将处理导致数据包丢失的拥塞问题


对于问题的线程部分,我们需要更多的信息。哪些资源是共享的,它们是否共享
TcpClient
,等等…

如果您需要大量性能,我建议使用缓冲池并手动执行读取(套接字上的Read())。共享缓冲区可以避免产生垃圾,因为我相信ReadLine()会产生一些垃圾

因为您使用的是TCP,所以数据丢失应该不是问题

在多线程设置中,您必须是特定的,但一般来说,资源共享很麻烦,因为它可能会产生数据竞争

为什么不使用a来确保您的阅读效果最佳:

var req = (HttpWebRequest)WebRequest.Create("http://www.stackoverflow.com");
using(var resp = (HttpWebResponse)req.GetResponse())
using(var stream = resp.GetResponseStream())
using(var bufferedStream = new BufferedStream(stream))
using(var streamReader = new StreamReader(bufferedStream))
{
    while(!streamReader.EndOfStream)
    {
        string currentLine = streamReader.ReadLine();
        Console.WriteLine(currentLine);
    }
}

当然,如果您希望扩展,那么异步将是必要的。因此,
ReadLine
是不可能的,您又回到了字节数组操作。

我会读入字节数组。。。。唯一的缺点是:尺寸有限。您需要知道某个字节数量限制,或者有时手动将字节数组刷新为字节集合,然后将集合转换回字节数组,还需要使用bitConverter将其转换为字符串,最后将其拆分为实际消息:p

将数组刷新到集合中会有大量开销。。。但是,刷新到字符串中需要更多的资源,因为在将字节刷新到字符串中时必须对其进行解码。。。。所以这取决于你。。。您可以选择字符串的简单性,也可以选择字节的高效性,无论哪种方式,它们之间的性能提升都不太明显,但我个人会选择字节集合,以避免隐式的字节转换


重要提示:这来自于以前使用TCP套接字的个人经验(Quake RCON之类的),而不是任何书籍或任何东西:)如果我弄错了,请纠正我。

谢谢您的帮助。是的,性能是一个主要问题,但是您认为,读入byteArray、转换为字符串、检查部分消息和拆分消息不会带来额外的开销,而且性能会更好吗?在共享资源的情况下,主要问题是客户机上的内存空间。@Danish,一点字符串操作几乎肯定比多个IO调用快。我认为使用BufferedStream不适合我的要求。正如我前面提到的,网络流将有大量的传入数据包,除非客户端发送终止请求,否则它不会终止。使用BufferedStream将意味着无限阻塞,首先将所有传入数据读入其中,这在这里是不可行的。据我所知,BufferedStream只是确保传入数据的读取以缓冲区大小的块进行,而不是以您请求的速率进行。例如,如果从流中读取数据的大小小于流的缓冲区大小,则读取效率低下。缓冲流通过将读取与缓冲区大小对齐来解决此问题。因此,它永远不会保存超过缓冲区容量的数据,但会使您的读取效率更高。它不会缓冲整个流。即使我也有类似的想法,但当我试图通过设置缓冲区大小来实现它时,它导致了一个错误“流不支持seek”。如果我没有设置缓冲区大小,它会无限期地等待。谢谢你的建议,但是我有点不清楚你建议如何使用缓冲区池,你能详细说明一下吗,一个示例代码片段就很好了。。再次感谢。我想,我应该读取2048大小的字节数组,将其转换为字符串,然后将其拆分为单个消息字符串。使用字节收集会增加复杂性,但不会带来太多好处。。谢谢你的帮助。