【问题标题】:Motorola EMDK - Thread blocking issues using Barcode2 ScanBufferStart and ScanBufferStopMotorola EMDK - 使用 Barcode2 ScanBufferStart 和 ScanBufferStop 的线程阻塞问题
【发布时间】:2013-10-11 18:29:59
【问题描述】:

我在 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();

我在两种情况下使用 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
    }
}

其次,当应用程序关闭时。

我的问题是,当调用 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()。

我也试过打电话 System.Threading.Thread.Sleep(0); 但这没有帮助。

是否有人对缓冲扫描模式有任何类似的经验,或者可能有解决方案的一般线程/锁定问题?

谢谢

【问题讨论】:

    标签: multithreading compact-framework barcode motorola-emdk


    【解决方案1】:

    在我看来,您不应该使用缓冲扫描模式。它确实适用于用户尽可能快地扫描并且应用程序实际上只是消耗缓冲区中的扫描的情况,而不是 IMO 更常见的方法,即每次扫描都由应用程序接收并立即验证。在缓冲模式下,用户可能比您的验证程序提前 2 或 3 次扫描,这显然效果不佳。

    事实上,我在 SDK 文档中发现了关于缓冲扫描的内容:

    注意:缓冲扫描模式可能不适合那些 需要在继续之前验证每次扫描的应用程序 读取下一个条形码。

    symbolBarcode2.ScanBufferStart() 的 Intsead 使用 symbolBarcode2.Scan()。它仍然是异步的,只是没有缓冲。

    【讨论】:

    • 我们从使用 .Scan() 开始,每次都在事件中调用它。从验证的角度来看,这很有效,因为您可以保证在“坏”条码之后不会扫描任何条码。但我们的问题是我们仍然想让用户尽可能快地扫描。我们将验证逻辑优化到
    • 您是否尝试过 Pause/Resume 变体,看看它们是否更能容忍从回调中调用?
    • EMDK 被混淆了,但我可以阅读足够多的内容,看到它正在等待ManualResetEvent,在正确的条件下,它是读取循环中的Set。看起来有十几种方式调用Set,所以希望他们密切关注他们的逻辑。浏览代码的一个想法是,您是否尝试过在停止和/或恢复之前调用ScanBufferClear?也许它试图在停止之前用缓冲区中剩余的任何东西给你回电,这肯定会死锁。
    • 好的,尝试调用 ScanBufferClear。查看调用堆栈,ScanBufferClear 调用 ScanBufferPause,然后调用 WaitOne...所以没有运气...
    • 我发现在_Closing()事件中直接调用ScanBufferStop()不会导致死锁。我使用的是从扫描委托所必需的线程调用它的相同技术。如果我在扫描事件委托中执行任何同步 UI 操作,我也会发现时间问题。例如消息框。直到关闭消息框后,它才会调用 ScanBufferStop ,这违背了目的。但是,我也可以通过从另一个线程调用扫描事件来解决此问题。到目前为止,这运作良好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多