0

こんにちは仲間のプログラマー!

バーコード リーダー ハードウェアを備えた Windows Mobile 6.1 デバイス用の Windows Forms .NET Compact Framework 2.0 を開発しています。

バーコードリーダーを使用してバーコードを読み取ることができ、有効化および無効化することもできます。ただし、何かを読み取ろうとして次のフォームに移動すると、objectdisposedexception が発生します。これは、バーコード リーダーのインスタンスを破棄してから、次のフォームで新しいインスタンスを作成する必要があるためです (推測)。

問題は、ボタンを使用して次のフォームに移動するときに、同じコードを使用してバーコードリーダーを破棄すると、objectdisposedexception が発生しないことです。textchanged イベントにフォーム ロードを単純に配置すると、エラーが発生しますが、try/catch ステートメントによってキャッチされず、アプリケーションがクラッシュします。

Windows Mobile への VS エミュレーターがデバイスのバーコードリーダー DLL で動作しないため、デバッグもできません。

誰かが私を助けることができますか?

コードは次のとおりです。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;

//DLL that controls the barcodereader
using Intermec.DataCollection;

namespace WOPT_Coletor.view.ConsultarPosicao
{
    public partial class frmConsultarPosicao_2 : Form
    {

        public BarcodeReader leitor;

        public frmConsultarPosicao_2()
        {
            InitializeComponent();
            ShowHide.ShowTopStatusbar(false);

            //code to work with the barcode reader
            model.LeitorCodigoDeBarras classeLeitor = new model.LeitorCodigoDeBarras();
            leitor = classeLeitor.LerCodigoDeBarras();
            leitor.BarcodeRead += new BarcodeReadEventHandler(this.eventoLeitorCodigoDeBarrasArmazenagem1);
        }    

        //Event to receive the barcode reading information
        void eventoLeitorCodigoDeBarrasArmazenagem1(object sender, BarcodeReadEventArgs e)
        {
            tbCodMaterial.Text = e.strDataBuffer.Trim();
        }

        private void tbCodMaterial_TextChanged(object sender, EventArgs e)
        {
            try
            {
                if (tbCodMaterial.Text.Length == 23)
                {                        
                    Cursor.Current = Cursors.WaitCursor;
                    Cursor.Show();

                    //disposal of the barcodereader instance
                    leitor.ScannerOn = false;
                    leitor.ScannerEnable = false;
                    leitor.Dispose();
                    leitor = ((BarcodeReader)null);

                    //processing of the information read.
                    char[] auxcodMaterial = new char[9];

                    using (StringReader str = new StringReader(tbCodMaterial.Text))
                    {
                        str.Read(auxcodMaterial, 0, 8);
                    }    
                    string codMaterial = new string(auxcodMaterial);

                    //loads next form
                    Form destino = new frmConsultarPosicao_3(codMaterial);
                    destino.Show();

                    Cursor.Current = Cursors.Default;
                    Cursor.Show();

                    //closes and dispose of the current form
                    this.Close();
                    this.Dispose(true);
                }    
            }

            catch (ObjectDisposedException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
}
4

1 に答える 1

1

バーコードリーダーのAPIと動作について詳しく知らなくても、tbCodMaterial_TextChanged内にいるときにBarCodeReadイベントが発生する可能性のある競合状態があると思います。スキャナーを無効にするコードの周りに同期ブロックを配置することをお勧めします。ブロック内では、スキャナーがnullでない場合にのみシャットダウンを実行します。

private readonly Object mySynchronizationObject = new Object;
...
lock (mySynchronizationObject)
{
    if (leitor != null)
    {
         //disposal of the barcodereader instance
         ...
    }
}

また、シャットダウンする前に(上記のロック内で)イベントから切断しても問題はありません。

leitor.BarcodeRead -= new BarcodeReadEventHandler(this.eventoLeitorCodigoDeBarrasArmazenagem1);
于 2013-02-28T17:56:11.237 に答える