带有事件处理程序的 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!");
}
我正在从 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!");
}