带有事件处理程序的 C# TcpClient streamreader 并非所有消息都被处理

C# TcpClient streamreader with eventhandler not all messages are processed

我正在从 TcpClient 流阅读器连续阅读。 来自流的数据是原始数据 XML。没有消息框架。所以现在有可靠的方法可以知道消息何时结束。虽然我只有 3 XML 条消息来自服务器。但他们什么时候来是未知的。而且我无法 configure/program 服务器。 到目前为止,这是我的代码。

        public void Start()
    {
        StreamReader reader = new StreamReader(_tcpClient.GetStream());
        char[] chars = new char[Int16.MaxValue];
        while (!_requestStop)
        {
            try
            {
                while ((reader.Read(chars, 0, chars.Length)) != 0)
                {
                    string s = new string(chars);
                    s = removeEmptyChars(s);
                    if (s.IndexOf("<foo", StringComparison.OrdinalIgnoreCase) > 0 &&
                        s.IndexOf("</foo>", StringComparison.OrdinalIgnoreCase) > 0)
                    {
                        Console.WriteLine(s);
                        OnAlarmResponseComplete(new CustomEventArgs(s));
                    }
                    if (s.IndexOf("<bar", StringComparison.OrdinalIgnoreCase) > 0 &&
                        s.IndexOf("</bar>", StringComparison.OrdinalIgnoreCase) > 0)
                    {
                        Console.WriteLine(s);
                        OnAckComplete(new CustomEventArgs(s));
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                //break;
            }
        }
        reader.Close();
        Console.WriteLine("Stopping TcpReader thread!");
    }

然后在我的主线程中处理事件。我正在将它们添加到列表中。 我在哪里处理列表。 当我调试我的应用程序时,我将收到 10 个 foo 和 10 个 bar 消息。在我的列表中,我只存储了 1 个 foo 和 1 个 bar 消息。

事件处理程序是否会减慢处理速度?还是我遗漏了什么?

这是您应该用来解决各种输入问题的代码(部分接收到 foo 或 bar,同时接收到 foo 和 bar,等等)

我不能说我赞成使用字符串解析来处理 XML 内容,但无论如何。

private static string ProcessAndTrimFooBar(string s, out bool foundAny)
{
    foundAny = false;

    int fooStart = s.IndexOf("<foo", StringComparison.OrdinalIgnoreCase);
    int fooEnd = s.IndexOf("</foo>", StringComparison.OrdinalIgnoreCase);
    int barStart = s.IndexOf("<bar", StringComparison.OrdinalIgnoreCase);
    int barEnd = s.IndexOf("</bar>", StringComparison.OrdinalIgnoreCase);

    bool fooExists = fooStart >= 0 && fooEnd >= 0;
    bool barExists = barStart >= 0 && barEnd >= 0;

    if ((fooExists && !barExists) || (fooExists && barExists && fooStart < barStart))
    {
        string fooNodeContent = s.Substring(fooStart, fooEnd - fooStart + 6);
        s = s.Substring(fooEnd + 6);
        Console.WriteLine("Received <foo>: {0}", fooNodeContent);
        OnAlarmResponseComplete(new CustomEventArgs(fooNodeContent));
        foundAny = true;
    }

    if ((barExists && !fooExists) || (barExists && fooExists && barStart < fooStart))
    {
        string barNodeContent = s.Substring(barStart, barEnd - barStart + 6);
        s = s.Substring(barEnd + 6);
        Console.WriteLine("Received <bar>: {0}", barNodeContent);
        OnAckComplete(new CustomEventArgs(barNodeContent));
        foundAny = true;
    }

    return s;
}

public static void Start()
{
    StreamReader reader = new StreamReader(_tcpClient.GetStream());
    char[] chars = new char[Int16.MaxValue];
    while (!_requestStop)
    {
        try
        {
            int currentOffset = 0;
            while ((reader.Read(chars, currentOffset, chars.Length - currentOffset)) != 0)
            {
                string s = new string(chars).TrimEnd('[=10=]');

                bool foundAny;

                do
                {
                    s = ProcessAndTrimFooBar(s, out foundAny);
                } while (foundAny);

                chars = s.PadRight(Int16.MaxValue, '[=10=]').ToCharArray();
                currentOffset = s.Length;
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            //break;
        }
    }
    reader.Close();
    Console.WriteLine("Stopping TcpReader thread!");
}