Motorola EMDK 2.7 で Symbol.Barcode2 オブジェクトを使用しています。非同期バッファ スキャン モードを使用しています。スキャン イベントごとに呼び出されるデリゲートをアタッチし、スキャナーを非同期バッファー モードで開始するサンプル コードを次に示します。
Barcode2 symbolBarcode2 = new Barcode2(Symbol.Barcode2.Devices.SupportedDevices[0]);
symbolBarcode2.OnScan +=new Barcode2.OnScanHandler(symbolBarcode2_OnScan);
symbolBarcode2.ScanBufferStart();
スキャナーを停止するには、ScanBufferStop メソッドを呼び出します。
symbolBarcode2.ScanBufferStop();
次の 2 つのシナリオで ScanBufferStop を使用します。
まず、データを処理するときに、スキャナーを停止してユーザーに警告したいと考えています。例:
private void symbolReader_OnScan(ScanDataCollection scancollection)
{
if (scancollection.GetFirst.Text == "0000000000")
{
// Turn off scanner and alert user
symbolBarcode2.ScanBufferStop();
}
else
{
// Process data and wait for next scan
}
}
2 つ目は、アプリケーションの終了時です。
私の問題は、ScanBufferStop が呼び出されると、アプリケーションがフリーズすることです。コール スタックをデバッグして調べると、Symbol.Barcode2.Barcode2.ScanBufferStop() 内に WaitOne() への呼び出しがあることがわかります。
mscorlib.dll!System.PInvoke.PAL.Threading_Event_Wait(System.IntPtr handle = 1245201)
mscorlib.dll!System.Threading.EventWaitHandle.WaitOne() + 0x7 bytes
Symbol.Barcode2.dll!Symbol.Barcode2.Barcode2.ScanBufferStop() + 0x43 bytes
また、Symbol オブジェクトによって追加のスレッドが作成されていることもわかります。ScanBufferStop() が別のスレッドが Barcode2 オブジェクトにアクセスしているかどうかを確認し、アクセスしている場合は WaitOne を呼び出していると思います。しかし、デリゲートの同じスレッドから呼び出すと、デッドロック シナリオが発生します。
最初のシナリオでは、デリゲートから ScannBufferStop を呼び出す独自の新しいスレッドを作成することで回避できました。
private void symbolReader_OnScan(ScanDataCollection scancollection)
{
if (scancollection.GetFirst.Text == "0000000000")
{
// Turn off scanner and alert user
//symbolBarcode2.ScanBufferStop();
System.Threading.Thread t = new System.Threading.Thread(StopDelegate);
t.Start();
}
else
{
// Process data and wait for next scan
}
}
internal void StopDelegate()
{
symbolBarcode2.ScanBufferStop();
}
しかし、アプリケーションの終了時にまだデッド ロックの問題があります。別のスレッドから ScanBufferStop を呼び出す同じ手法を使用しようとしましたが、WaitOne() の呼び出しで 1 つのスレッドがハングしてしまいます。
System.Threading.Thread.Sleep(0); の呼び出しも試みました。しかし、それは役に立ちませんでした。
Buffered Scan Modeで同様の経験をした人はいますか、それとも解決策があるかもしれない一般的なスレッド/ロックの問題がありますか?
ありがとう