这种方法冻结了我的GUI,我不明白为什么。
特别是它被卡在while ((feedback = reader.ReadLine()) != null)
我试过通过检查reader.EndOfStream()并尝试相同的结果来打破循环。打印机按预期运行并打印标签,并且还返回预期的反馈。它只是坐在循环中,在控制台中闪烁光标。
我可以摆脱循环,因为我真的不需要这个程序的反馈,但我仍然想了解发生了什么。
它被称为这样:
private void printBarcodeButton_Click(object sender, RoutedEventArgs e)
{
...
code to get id and name
...
messageTextBlock.Text = "Printing Barcode.";
using (var printer = new BarcodePrinter())
{
printer.printBarcode(employeeID, employeeName);
}
messageTextBlock.Text = "Barcode printed.";
}
以下是方法:
public void printBarcode(string employeeID, string employeeName)
{
var projectFolder = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
var printerScript = Path.Combine(projectFolder, @"PrinterScript.txt");
// Printer IP Address and communication port
string ipAddress = "10.1.10.23";
int port = 9100;
// Fingerprint Commands read from text and sent to printer
using (TcpClient client = new TcpClient())
{
client.Connect(ipAddress, port);
using (var stream = client.GetStream())
{
// open the script file
using (var file = new StreamReader(printerScript))
{
// open a stream to get feedback from printer
string feedback = "none yet";
using (var reader = new StreamReader(stream))
{
// open stream to send commands to printer
using (var writer = new StreamWriter(stream))
{
string command, script = null;
while ((command = file.ReadLine()) != null)
{
// send all non-empty lines in script
if (command != string.Empty && !command.Contains("**"))
{
command = command.Replace("_employeeID_", employeeID);
command = command.Replace("_employeeName_", employeeName);
script += command + "\n";
}
}
writer.Write(script);
writer.Flush();
// display data sent back from printer (including echo of commands)
while ((feedback = reader.ReadLine()) != null)
{
Console.WriteLine(feedback);
}
}
}
}
}
}
}
答案 0 :(得分:1)
摘自MSDN:
一条线被定义为一个字符序列,后跟一个换行符(" \ n"),一个回车符(" \ r"),或者紧接着一个回车符通过换行符(" \ r \ n")。返回的字符串不包含终止回车符或换行符。如果到达输入流的末尾,则返回值为null。
您可能尚未达到\n
,\r
或\r\n
,也未达到输入的结尾。这里需要注意的是通常"输入结束"意味着另一个点(您的场景中的打印机)关闭了频道,而且很可能它没有这样做。
我建议在接收时使用超时,因为这些设备通常会立即发送所有数据。如果这个选项无效,还有其他选项,请问,但它应该在大多数情况下都有效。
答案 1 :(得分:0)
只需添加:
while ((feedback = reader.ReadLine()) != null)
{
Console.WriteLine(feedback);
if (feedback == "Ok") break;
}
它甚至在发生错误后发送Ok消息,因此涵盖了所有内容。
答案 2 :(得分:-1)
我没有在while条件中对命令进行赋值,而是尝试将它作为while语句中的最后一个命令:
string command, script = null;
command = file.ReadLine();
while (command != null)
{
// send all non-empty lines in script
if (command != string.Empty && !command.Contains("**"))
{
command = command.Replace("_employeeID_", employeeID);
command = command.Replace("_employeeName_", employeeName);
script += command + "\n";
}
command = file.ReadLine();
}
这种改变只会在检查while循环条件之前确保显式读取,并确保while循环中的赋值不是条件。