2

5秒ごとにシリアルポートをポーリングする(リクエストを送信してレスポンスを取得する)アプリケーションを1つ開発しました。すべてが非常にうまく機能していたので、徹底的にテストしました。

しかし、スレッド化を導入したときに、物理メモリに関するブルー スクリーン エラーが発生するか、スレッド化で以下に添付されているように、GUI 更新タスクとポーリング タスクを分離しました。

同じものを削除するにはどうすればよいか、誰かが私に提案できますか?

これは、アプリケーションを実行するたびに発生します。profic ドライバーのシリアル to USB ドライバーを使用しています。

主なアプリケーション コード

private void timer_Elapsed(object sender, ElapsedEventArgs e)
 {
PollingAllMeters();         
 }


 public void PollingAllMeters()
    {
        int isdbError = 0;
        PollingUtility.MeterClass mData = new PollingUtility.MeterClass();



        for (int index = 0; index < m_slaveID.Length; index++)
        {
            try
            {
                mData = poll.MeterOne(m_slaveID[index]);
                Thread processData = new Thread(() => this.updateData(data));
                processData.Start();
            }
            catch { MessageBox.Show("Inside polling box"); 
         }
      }


    private void updateData(MeterValues data)
    {

        mainFormRef.updateData(data);

    }

実際のリクエストとレスポンスが発生しているDLLコード

enter code here
public MeterClass MeterOne(byte meterID)
    {
        MeterClass data1 = new MeterClass();
                 //Voltage
        mb.SendFc3(meterID, startAdd, register, ref value_meter); //modbus call is made here for         sending and receiving response at serial port
        if (mb.modbusStatus == "Read successful")
        { 
             //do some calculation
        }
        else
        {
            // error handling code to create log file

            if (mb.modbusStatus == "Error in read event")
            {
                isPollError = 21;
            }
            else if (mb.modbusStatus == "CRC error")
            {
                isPollError = 22;
            }
            else if (mb.modbusStatus == "Serial port not open")
            {
                isPollError = 23;
            }
        }


        startAdd = 360;
        register = 2;

        value_meter = new byte[register * 2];
        meterData = new byte[register * 2];

        //Max demand
        mb.SendFc3(meterID, startAdd, register, ref value_meter);
        if (mb.modbusStatus == "Read successful")
        {
            //do some calculation

        }
        else
        {
            // error handling code to create log file

            if (mb.modbusStatus == "Error in read event")
            {
                isPollError = 21;
            }
            else if (mb.modbusStatus == "CRC error")
            {
                isPollError = 22;
            }
            else if (mb.modbusStatus == "Serial port not open")
            {
                isPollError = 23;
            }
        }


        startAdd = 496;
        register = 16;

        value_meter = new byte[register * 2];
        meterData = new byte[register * 2];

        mb.SendFc3(meterID, startAdd, register, ref value_meter);
        if (mb.modbusStatus == "Read successful")
        {
          //do some calcualtion

        }
        else
        {
            // error handling code to create log file

            if (mb.modbusStatus == "Error in read event")
            {
                isPollError = 21;
            }
            else if (mb.modbusStatus == "CRC error")
            {
                isPollError = 22;
            }
            else if (mb.modbusStatus == "Serial port not open")
            {
                isPollError = 23;
            }
        }

        data1.date = DateTime.Now;
        data1.Status = isPollError;
        return data1;      // return result to the main program

    }
4

1 に答える 1

2

シリアル ポートをエミュレートする USB および BlueTooth デバイス ドライバーは、信頼性が低いことで有名です。優秀なプログラマーにまともな賃金を支払うために多くのお金を残さないのは、ひどいビジネスだと思います。ドライバーの更新を入手できない場合にできる唯一のことは、それを破壊して、あなたの人生を悲惨なものにしないようにすることです. 駐車場に持って行き、車で数回ひっくり返します。

エンジンを起動する前に、コードをよく見てください。「マルチスレッド」は危険信号です。ドライバーは、複数のスレッドを使用するプログラムを認識しません。複数のスレッドから同時に Read または Write を呼び出すことができるシナリオは避けてください。ドライバーは常にそれに対して回復力がある必要がありますが、これがテストされることはあまりありません。必要に応じてコードを再調整して、1 つのスレッドのみがlockステートメントを読み書きまたは使用するようにします。

于 2013-09-19T19:06:06.803 に答える