以下是我正在尝试做的一些背景知识:
打开从移动设备到蓝牙打印机的串行端口.
将EPL/2表单发送到蓝牙打印机,以便它了解如何处理它将要接收的数据.
收到表格后,将一些数据发送到打印机,打印机将打印在标签纸上.
根据需要对每个要打印的标签重复步骤3.
第2步仅在第一次发生,因为表单不需要在每个标签之前.我的问题是,当我发送表单时,如果我发送标签数据太快,它将无法打印.有时我会在标签上打印"Bluetooth Failure:Radio Non-Operational"而不是我发送的数据.
我通过执行以下操作找到了解决问题的方法:
for (int attempt = 0; attempt < 3; attempt++) { try { serialPort.Write(labelData); break; } catch (TimeoutException ex) { // Log info or display info based on ex.Message Thread.Sleep(3000); } }
所以基本上,我可以捕获一个TimeoutException并在等待一定时间后重试write方法(三秒似乎一直在工作,但是更少,似乎每次尝试都抛出异常).经过三次尝试,我只是假设串口有问题,让用户知道.
这种方式似乎工作正常,但我确信有更好的方法来处理这个问题.我认为我需要使用SerialPort类中的一些属性,但我找不到任何好的文档或如何使用它们的示例.我试过玩一些属性,但它们似乎都没有做我想要达到的目标.
这是我玩过的属性列表:
CDHolding
CtsHolding
DsrHolding
DtrEnable
握手
RtsEnable
我相信这些的一些组合将处理我想要更优雅地做的事情.
我正在使用C#(2.0框架),Zebra QL 220+蓝牙打印机和Windows Mobile 6手持设备,如果这对解决方案有任何影响.
任何建议,将不胜感激.
[UPDATE]
我还应该注意到移动设备使用的是蓝牙2.0,而打印机只使用1.1版本.我假设速度差异是导致打印机在接收数据时落后的原因.
我已经根据已经给出的两个建议找到了一种方法.我需要使用以下内容设置我的串口对象:
serialPort.Handshake = Handshake.RequestToSendXOnXOff; serialPort.WriteTimeout = 10000; // Could use a lower value here.
然后我只需要进行写调用:
serialPort.Write(labelData);
由于Zebra打印机支持软件流控制,因此当缓冲区接近满时,它将向移动设备发送XOff值.这使得移动设备等待从打印机发送XOn值,有效地通知移动设备它可以继续发送.
通过设置写入超时属性,我将在抛出写入超时异常之前给出传输所允许的总时间.您仍然希望捕获写入超时,就像我在问题中的示例代码中所做的那样.但是,由于软件流控制将启动和停止串行端口写入传输,因此没有必要循环3次(或任意数量)次,尝试每次写入.
流量控制是正确的答案,它可能不会出现/实施/适用于您的蓝牙连接.
查看Zebra规范并查看它们是否实现,或者是否可以打开软件流控制(xon,xoff),这将允许您查看各种缓冲区何时变满.
此外,蓝牙无线电不可能最大传输速度超过250k.您可以考虑人为地将其限制为9,600bps - 这将使无线电为重传,纠错,检测和自身的流量控制留出很大的喘息空间.
如果所有其他方法都失败了,那么你现在正在使用的黑客并不坏,但是我会打电话给Zebra技术支持并在放弃之前找出他们推荐的内容.
-亚当