15

シリアル ポートからデータを読み取るコードを次に示します。物事を単純にするために、ボタンのクリックでそれを行いましょう。

    private System.IO.Ports.SerialPort serialPort;

    private void button1_Click(object sender, EventArgs e)
    {
        if (serialPort == null)
            serialPort = new SerialPort("COM7", 4800, Parity.None, 8, StopBits.One);
            //COM7 is hard coded just for the sake of example

        if (!serialPort.IsOpen)
            serialPort.Open();

        textBox1.AppendText(serialPort.ReadExisting());
    }

私のラップトップがスリープ状態にならない限り、コードは完全に正常に動作します。システムがスリープから復帰すると、serialPortオブジェクトは返されnullず、 「要求されたリソースは使用中です」というエラーが表示されます。通話中。内部例外には何もありません。serialPort.IsOpenfalseserialPort.Open()ここに画像の説明を入力

オブジェクトを閉じる、破棄する、明示的にnullに割り当てて再初期化するなど、オブジェクトで多くのことを試しましserialPortたが、役に立たず、毎回同じ行で同じエラーが発生します。

        if (!serialPort.IsOpen)
        {
            try
            {
                serialPort.Open();
            }
            catch
            {
                serialPort.Close();
                serialPort.Dispose();
                serialPort = null;

                serialPort = new SerialPort("COM7", 4800, Parity.None, 8, StopBits.One);
                serialPort.Open();
            }
        }

イベントも試しserialPort.DataReceivedましたが、システムがスリープから復帰すると、イベントは発生しません。

唯一の回避策は、アプリケーションを停止して再度実行することです。誰かがまともな方法でそれを整理する手がかりをくれれば、本当に感謝します.

4

1 に答える 1

8

SystemEvents.PowerModeChangedコメントで提案したように、イベントを使用してシステムが一時停止しようとしていることを検出することで回避策を作成できます。その状態が検出されたら、シリアル ポートを閉じて、オペレーティング システムがサスペンド状態から再開しようとしているときに再度開く必要があります。

hamad は、この回避策が機能することを確認しました。

これがコードです。

SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;

void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
    if (e.Mode != PowerModes.Resume)
        serialPort.Close();
}

イベントのドキュメントからも注意してください:

注意

これは静的イベントであるため、アプリケーションが破棄されるときにイベント ハンドラーをデタッチする必要があります。そうしないと、メモリ リークが発生します。

于 2012-08-27T10:02:08.073 に答える