1

主に Xbee と PC 間の COM ポート通信を含む winform プログラムに取り組んでいます。最初に問題を表示させてください。

ノート:

  1. デリゲート関数について心配する必要はありません。返されるバイトをチェックするだけです

  2. プログラムは以前は機能していましたが、今日は高速設定を追加しました。したがって、xbee デバイスの場合、9600 の速度から始めて、必要な速度 (38400) に変更する必要があります。次回デバイスを接続すると、速度は@ 38400のままです。これが、別の baud_rate に接続しようとする if(initial_fail) ブロックを追加する理由です。

  3. 数字でマークしたコメントに従ってください

        try
        {
            portBuffer.Clear();
            myComPort.Write(myxbee.myxbee_cmd.cmd_mode, 0, myxbee.myxbee_cmd.cmd_mode.Length);   //RETURN OK <CR> 
    
            IAsyncResult res = d.BeginInvoke(null, null);
            if (res.IsCompleted == false)
            {
                res.AsyncWaitHandle.WaitOne(2000, false);
                if (res.IsCompleted == false)
                    initial_fail = 1; //1. start from here, once there is a timeout, set the initial_fail to 1, Time-out because the baudrate is not sync
                 if (d.EndInvoke(res) == false)
                   throw new Exception("Failing to enter the cmd mode");
            }
        }
        catch (ApplicationException e)
        {
            MessageBox.Show(e.Message);
            return false;
        }
        catch (Exception e)
        {
            MessageBox.Show("Error at step 1: {0}", e.Message);
            return false;
        }
        //2. here is the new code I added today
        if (initial_fail == 1)
        {
            myComPort.BaudRate = 38400; //3. Here I changed the speed and gui text
            cmbBaudRate.Text = "38400"; //PROBLEM: when Im doing step by step debug, seems like these two lines doesnt get executed. Winform GUI remain unchanged
            try
            {
    
                portBuffer.Clear();
                myxbee.command_buffer.Clear();
                dummy = "05";
                dummy_byte = Encoding.ASCII.GetBytes(dummy);
                myxbee.command_buffer.AddRange(myxbee.myxbee_cmd.data_rate); 
                myxbee.command_buffer.AddRange(dummy_byte);
                myxbee.command_buffer.Add(myxbee.myxbee_cmd.line_feed);
                myComPort.Write(myxbee.command_buffer.ToArray(), 0, myxbee.command_buffer.ToArray().Length);
                IAsyncResult res1 = d.BeginInvoke(null, null);
                if (res1.IsCompleted == false)
                {
                    res1.AsyncWaitHandle.WaitOne(1000, false);
                    if (res1.IsCompleted == false)
                        throw new ApplicationException("Timeout"); 
                        //4. since the winform hasnt shown any bd_rate change, the program will throw a time-out here again 
                }
                if (d.EndInvoke(res1) == false)
                    throw new Exception("Fail in setting data rate to 38400");
                chkHighSpeed.Checked = true;
                high_speed_set = 1;
                MessageBox.Show("Xbee high speed");
            }
            catch (ApplicationException e)
            {
                MessageBox.Show(e.Message);
                return false;
                //5. BUT AFTER THIS TIMEOUT message, the winform's GUI will be updated to 38400, and rerun the whole test will pass
            }
    

これは GUI の一部で、次のようになります。 ここに画像の説明を入力

だから私の質問は、タイムアウト例外の後でのみボーレートが更新されるのはなぜですか?

4

1 に答える 1

0

問題は、UIと同じスレッドでプロセスを作成するという事実に起因していました。したがって、UIはcomプロセスによってフリーズできます。UIを更新するdoeventsメソッドを使用して問題を解決することはできますが、それはあなたの場合には最善の方法ではありません。バックグラウンドワーカーを使用して、comプロセスを別のスレッドで起動します。

于 2012-08-12T03:03:34.683 に答える