バーコード スキャナーは非同期的に動作するため、データが使用可能になったら、またはデバイスの状態が変化したら、アプリケーションに通知する必要があります。 このタスクを実行するには、.NET デリゲートを使ってアプリケーションへのイベントを発生させます。
「デバイスの入力とイベント」トピックで説明されているように、イベントはアプリケーションに配信される前にキューに入れられます。 Microsoft Point of Service for .NET (POS for .NET) の Base クラスでは、アプリケーションが処理できるようになるまでアプリケーションへのイベントの配信を遅延できるよう、サービス オブジェクトのコードでイベントをキューに入れるための手段が提供されています。 その間、サービス オブジェクトは、追加の受信ハードウェア イベントを待ち続けることができます。
スキャナー デバイスは、アプリケーションに 4 つのイベントを送信できます。 これらのイベントのうち DataEvent と ErrorEvent の 2 つについては、POS for .NET の ScannerBase クラスに、これらのイベントを発生させるために必要なコードを簡略化するための、保護されたヘルパー メソッドが用意されています。
| イベント | イベントをキューに格納するメソッド |
|---|---|
| DataEvent | 保護されたメソッド ScannerBase.GoodRead |
| ErrorEvent | 保護されたメソッド ScannerBase.FailedRead |
他の 2 つのイベント DirectIOEvent と StatusUpdateEvent は、下位レベルの ScannerBasic クラスのメンバーを使って発生させる必要があります。 詳しくは、「デバイスの入力とイベント」をご覧ください。
スキャナー デバイスは、いつでもシステムにデータを配信できるため、スキャナー サービス オブジェクトは、別のリーダー スレッドを開始してデータを非同期に待機する必要があります。 デバイスからデータが到着したら、このスレッドからイベントをキューに登録する必要があります。
デバイスの入力に基づいてイベントを発生させるには
デバイスからの入力を待機するためのリーダー スレッドを開始します。
リーダー スレッドで入力を待ちます。一般に、Win32 の直接関数を使って USB バスからデータを読み取ります。
データを受信したら、データが有効であることを確認します。たとえば、パケットにヘッダーとデータ型のための十分なバイトがあることを確認します。
データが有効ではない場合は、ScannerBase.FailedScan メソッドを呼び出して、アプリケーションで発生する ErrorEvent イベントをキューに登録します。
データが有効な場合は、ScannerBase.GoodScan メソッドを呼び出して、アプリケーションで最終的に発生する DataEvent イベントをキューに登録します。
例
デバイスから入力を受信するとすぐに、サービス オブジェクトは適切なイベントをキューに登録します。 このトピックのサンプルのもののような、サービス オブジェクトのリーダー スレッドから呼び出されるメソッドを記述することで、これを行うことができます。
// A Service Object may implement a method such as this one to
// be called from the reader thread of the Service Object.
void OnDataScanned(byte[] data)
{
// Ignore input if process in the Error state. There is no
// need to send an ErrorEvent to the application, because it has
// already been notified by this point.
if (State == ControlState.Error)
{
return;
}
// Make sure that the incoming buffer is large enough to contain
// at least the header and type data.
if ((int)data[1] < 5)
{
// By calling FailedRead, you are queueing an
// ErrorEvent for eventual delivery to the application.
FailedScan();
}
else
{
// The buffer received from the device will be longer
// than we need. Therefore, trim it down. Allocate space for
// the number of bytes contained in data[1], plus one
// more for the first byte in the buffer.
byte[] b = new byte[(int)data[1] + 1];
// Copy the data into a new buffer.
for (int i = 0; i <= (int)data[1]; i++)
{
b[i] = data[i];
}
// By calling GoodScan, you are queueing a DataEvent
// which will delivered to the application when it is suitable.
GoodScan(b);
}
}
このサンプルをそれだけでコンパイルすることはできませんが、完全なスキャナー サービス オブジェクトの実装に挿入できます。
参照
タスク
概念
その他の参照情報
.NET