某些 POS 设备类型支持打印或显示输出,例如 PosPrinter 或 LineDisplay。 为已启用输出的设备编写的服务对象应支持异步输出和同步输出。
异步执行操作的应用程序在调用所需的输出方法之前,会将服务对象的 AsyncMode 属性设置为 true。 如果服务对象无法异步处理请求,则可能会引发异常,但这并不理想,因为它限制了可能使用该特定服务对象的应用程序的范围。
但是,支持异步输出可能需要其他可能复杂的代码。 此代码将管理传入请求的队列,维护一个线程以监视队列并按正确的顺序调度请求,并将事件引发回应用程序。
Microsoft Point of Service for .NET (POS for .NET) 基类可以为开发人员管理所有这些任务。 对于每个输出方法,基类都有一个与每个输出方法关联的帮助程序方法。 这些以 Impl 后缀结尾的方法的编写,就像它们只是其父方法的同步实现一样。 基类以透明方式管理队列,以正确顺序在正确的时间将请求调度到 Impl 函数,并引发相应的事件,返回到应用程序。 对于同步操作和异步操作,调用相同的方法。
通过派生自 POS for .NET 基类,服务对象无需实现其他代码即可获取异步功能。
基类实现
POS for .NET 为 POS 设备类型的子集提供基类。 对于这些类中的每个输出方法,都有一个具有 Impl 后缀的相应方法。 派生自基类的服务对象应仅重写 Impl 方法,而不应重写相应的父方法。 例如,在派生自 POS for .NET 基类 PosPrinterBase 的类中,服务对象将提供 PrintNormalImpl 的实现,并且不会重写 PrintNormal。
POS for .NET 基类实现所有输出方法并执行以下任务,以支持由服务对象实现的 Impl 方法:
- 验证参数。
- 如果 AsyncMode 属性为 false,则立即调用相应的 Impl 方法。
- 如果 AsyncMode 属性设置为 true:
- 请求置于队列中。 此队列由 POS for .NET 拥有,并由其自己的线程管理。
- 队列上的请求由队列的线程检查,并调用相应的 Impl 方法。 如果设备已在处理输出请求,或者队列上存在优先级更高的请求,则此调用可能会延迟。
- 当 Impl 方法返回时,POS for .NET 基类代码将处理所有结果。 对于同步调用,该方法可能会返回值或引发异常。 对于异步调用,该方法可能会将 OutputCompleteEvent 或 ErrorEvent 事件引发回应用程序。
- Impl 方法还可以返回一个对象,该对象不仅包含错误信息,还包含统计信息值。
服务对象 Impl 方法
由于大多数处理都由基类代码处理,因此服务对象的 Impl 方法可能相对简单。
在许多情况下,Impl 方法需要原始调用时设备的状态。 在这些情况下,基类代码将保存当前设备状态以及输出请求。 设备状态稍后作为参数发送到 Impl 方法。 例如,PrintNormalImpl 的定义是:
protected override PrintResults PrintNormalImpl(
PrinterStation station,
PrinterState printerState,
string data);
上述参数 printerState 特定于 Impl 方法,不存在于 PrintNormal(PrinterStation, String) 定义中。
Impl 函数的返回值也不同于其调用方法。 例如,请注意,PrintNormalImpl 方法返回类型 PrintResults 的类。 除了 ErrorCode、ErrorCodeExtended、ErrorLevel 和 ErrorString 之外,调用方法还将使用其他许多属性来更新统计信息计数。
示例
以下示例演示了如何在服务对象代码中实现这些方法。
protected override PrintResults PrintNormalImpl(
PrinterStation station,
PrinterState printerState,
string data)
{
// First, create a PrintResults object to hold return values.
PrintResults pr = new PrintResults();
// Now print, depending on the station.
if (station == PrinterStation.Receipt)
{
// Your code goes here.
// Update statistics to be returned to the caller.
pr.ReceiptLinePrintedCount = 1;
pr.ReceiptCharacterPrintedCount = data.Length;
}
else if (station == PrinterStation.Slip)
{
// Your code goes here.
// Update statistics to be returned to the caller.
pr.SlipLinePrintedCount = 1;
pr.SlipCharacterPrintedCount = data.Length;
}
return pr;
}