过去几天我一直在尝试使用BeginRead和Read方法从NetworkStream对象中读取,但是这两种方法都给我带来了困难并且似乎不可靠
第一个,“Read”要求我睡眠线程,并期望睡眠结束时存在正确的数据。 像这样:
cmd = System.Text.Encoding.ASCII.GetBytes(CommandString + "\r");
ns.Write(cmd, 0, cmd.Length);
Thread.Sleep(5000);
int _bytes = ns.Read(output, 0, output.Length);
responseOutput = System.Text.Encoding.ASCII.GetString(output, 0, _bytes);
Console.Write(responseOutput);
这有80%的时间是因为服务器的延迟在一天中波动,我也尝试了下面的方法,我觉得构造不好,最有效的方法是轮询数据,匹配一组不燃烧CPU的条件也不浪费时间?
bool connection_check = false;
String[] new_connection_array = new String[] { "processed successfully", "invalid", "Command not recognised. Check validity and spelling" };
do
{
int view_bytes = ns.Read(output, 0, output.Length);
responseOutput += System.Text.Encoding.ASCII.GetString(output, 0, view_bytes);
foreach (String s in new_connection_array)
if (responseOutput.IndexOf(s) > -1)
connection_check = true;
} while (connection_check == false);
提前致谢
编辑:
public bool SendCommandAndWait(Byte[] command, Regex condition)
{
if (callback == null)
{
SendCommand(command);
callback = ar =>
{
int bytesEnd = ns.EndRead(ar);
int bytes = bytesEnd;
// Process response
responseOutput += System.Text.Encoding.ASCII.GetString(output, 0, bytes);
// Check if we can return
if (condition.IsMatch(responseOutput))
return; // Yes, there is a match... return from the async call
else // No match, so loop again
ns.BeginRead(output, 0, output.Length, callback, null); // Call the loop again
};
ns.BeginRead(output, 0, output.Length, callback, null);
}
// Because the callback is fired into a different thread and the program continues, we need to loop here so the program doesn't continue without us
do
{
Thread.Sleep(1000);
//Console.WriteLine(responseOutput);
} while (!condition.IsMatch(responseOutput));
if (condition.IsMatch(responseOutput))
{
callback = null;
return true;
}
else
return false;
}
答案 0 :(得分:0)
BeginRead将允许您定义beginread完成时执行的操作。请注意,这与您阅读要阅读的所有内容时的内容不同。这就是read返回读取的字节数的原因。如果您希望读取20个字节并获得10个字节,则需要再读取10个字节。
来自https://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.beginread(v=vs.110).aspx:
BeginRead方法读取尽可能多的数据,最多可达size参数指定的字节数。
如果您希望在调用BeginRead方法后阻止原始线程,请使用WaitOne方法。