我在使用StreamReader / StreamWriter读取多条消息时遇到问题

时间:2018-04-16 05:35:39

标签: c# asynchronous

我需要在客户端收听多条消息,但ReadLineAsync()只读取第一条消息。

    //Server Side
    StreamWriter StwWriter = new StreamWriter(client.GetStream())
    {
        AutoFlush = true
    };
    for (int i = 0; i < 10; i++)
    {
        StwWriter.WriteLine("test");
    }
    // Client Side
    public async void WaitMessages()
    {
        while (LoginChat.Client.Connected)
        {
            try
            {
                var reader = new StreamReader(LoginChat.Client.TcpClt.GetStream());
                var data = await reader.ReadLineAsync();
                MessageBox.Show(data);
            }
            catch (Exception ex)
            {
              MessageBox.Show(ex.ToString());  
            }
        }
    }
    WaitMessages();

输出仅显示第一条消息。有什么问题?

3 个答案:

答案 0 :(得分:3)

StreamReader有内部缓冲区,所以当你这样做时:

var reader = new StreamReader(LoginChat.Client.TcpClt.GetStream());
var data = await reader.ReadLineAsync();

它可能已阅读多行。如果您继续使用相同的StreamReader实例来获取下一行,那么这不是问题,但您只需读取一行然后放弃StreamReader。这意味着其缓冲区中的所有内容都将丢失。

要修复 - 不要在每次循环迭代中创建新的StreamReader,而是使用一个实例:

public async Task WaitMessages()
{
    var reader = new StreamReader(LoginChat.Client.TcpClt.GetStream());
    while (LoginChat.Client.Connected)
    {
        try
        {                
            var data = await reader.ReadLineAsync();
            MessageBox.Show(data);
        }
        catch (Exception ex)
        {
          MessageBox.Show(ex.ToString());  
        }
    }
}

答案 1 :(得分:1)

正如我在评论中所提到的,你需要在while循环外创建steam,所以代码应该是这样的,它会导致问题,因为你每次在代码中创建流

public async Task WaitMessages()
{
    var reader = new StreamReader(LoginChat.Client.TcpClt.GetStream());
    while (LoginChat.Client.Connected)
    {
        try
        {                
            var data = await reader.ReadLineAsync();
            MessageBox.Show(data);
        }
        catch (Exception ex)
        {
          MessageBox.Show(ex.ToString());  
        }
    }
}

答案 2 :(得分:0)

问题是reader.readlineasync(),只会从文本流中获取第一行。为了获得其他文件,应该连续读取该文件,直到下一行读取为空。查看此链接,了解其完成情况https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-read-a-text-file-one-line-at-a-time