0

シリアルポート接続中にC#インターフェイスがフリーズする理由について質問があります。有効なシリアルポート(期待するバイト数を送信するデバイス)に接続しても、インターフェイスがフリーズしません。ただし、ユーザーがコンピューターの別のポートまたはデバイスの間違ったモデルに接続しようとすると、プログラムは「?」を送信したときにデータを返しません。文字などの最初の行:message [i] =(byte)port.BaseStream.ReadByte(); タイムアウトが発生し、キャッチに該当して3回接続を試みてから、接続の失敗をユーザーに警告します。UIは、3回の試行が行われた後は正常に機能しますが、実行中はUIが応答しません。何か案は?よろしくお願いします。以下は私のコードです。

public void windowLoop(object sender, EventArgs e)
    {
        if (Global.connecting)
        {
            try
            {
                if (i == 0) { port.BaseStream.Flush(); port.BaseStream.WriteByte(63); }
                message[i] = (byte)port.BaseStream.ReadByte();
                if (i == 6)
                {
                    connectAttempts = 1;
                    i = 0;
                    String result = Encoding.ASCII.GetString(message);
                    if (result == "ASUTTON")
                    {
                        //connection succeeded
                        Global.connecting = false;
                        Global.receiving = true;
                        setDisplay(2);
                    }
                    else
                    {
                        //connection failed
                        Global.connecting = false;
                        disconnect();
                        MessageBox.Show(radio, "You are not connection to an Agent (Radio Version)", "Connection Failed", MessageBoxButton.OK, MessageBoxImage.Information);
                    }
                }
                else
                {
                    i++;
                }
            }
            catch
            {
                if (connectAttempts >= connectAttemptsLimit)
                {
                    connectAttempts = 1;
                    Global.connecting = false;
                    disconnect();
                    MessageBox.Show(radio, "Your device failed to connect to the program.", "Connection Failed", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                else
                {
                   connectAttempts++;
                }
            }
        }
        else if (Global.sending)
        {

上記は、10ミリ秒ごとに実行するように設定されたDispatcherTimerオブジェクトを介して継続的に実行される私のコードです。

4

4 に答える 4

2

アプリケーションの応答性を維持するために、スレッドを使用することをお勧めします。シリアルポートとの通信はブロッキングコールであり、ポートが機能していないと判断する前にタイムアウトを待機します。

理想的な解決策は、バックグラウンドワーカーコンポーネントを使用して、シリアルポートへの接続を試行させることです。

于 2013-03-26T11:28:45.547 に答える
1

通信をシリアルポート経由で別のスレッドに移動するか、タイムアウトを低く設定してみてください。

于 2013-03-26T11:28:47.447 に答える
1

MSDNによるDispatcherTimerは次のとおりです。

指定された時間間隔および指定された優先度で処理されるディスパッチャーキューに統合されたタイマー。

これは、Dispatcherがメッセージを送信するのと同じスレッドで実行されることを意味します。したがって、タイマーリクエストの処理中に、キュー内の他のものの実行または処理を停止します。

これを解決するには、別のスレッドで実行されるSystem.Timers.Timerクラスイベントのserailポートに接続するコードを使用して、実行中にブロックされないようUIにします。

于 2013-03-26T11:29:52.143 に答える
1

を使用することも、 TPLを使用Threadすることもできます。Task次のようなSerialPortクラスで利用できるイベントもいくつかあります。DataReceived

Readからに変更してみませんかBeginRead。その後、を使用できますAsyncCallback

byte[] received = new byte[port.BytesToRead];
result = port.BaseStream.BeginRead(received 
            , 0, port.BytesToRead, new AsyncCallback(ReadCallBack), port.BaseStream);


private void ReadCallBack(IAsyncResult ar)
    {            
        Stream stream = (Stream)ar.AsyncState;

        // Do reading here?
    }
于 2013-03-26T11:41:10.410 に答える