3

SerialPort オブジェクトの外部から見ると、書き込みバッファーのサイズと、それがいっぱいかどうかに違いはないようです。

同期書き込みを使用すると、書き込みメソッドは、すべてのデータが送信されてバッファーが空になるまでブロックされます。

非同期書き込みを使用すると、データはキューに入れられ、プログラムは続行されます。書き込み操作が完了し、データがバッファからなくなるまで、コールバック メソッドは呼び出されません。

serialport オブジェクトの動作は、バッファ内のデータ量やバッファがいっぱいかどうかに関係なく同じようです。書き込みバッファがいっぱいになってもエラーは発生しないようです。

では、なぜ BytesToWrite と WriteBufferSize をチェックできるのでしょうか? 書き込みバッファがいっぱいになったときに SerialPort の動作が異なる方法はありますか?

4

3 に答える 3

1

バッファーは、バッファーを処理する人が自分の時間に自分の方法でそれを実行できるように設計されたメカニズムです。データを送信するときは、ポートの最大速度でプッシュする必要がありますが、ポートでビジー待機して、次のデータをプッシュする前に各バイトが送信されるのを待ちたくありません。したがって、ハードウェアにフィードする処理バッファーがあり、チャンクで渡すことができます。

BytesToWrite をチェックする理由については、次にやりたいことに移る前に、すべてのデータが送信されたかどうかを知りたい場合がよくあります。実際の転送速度などを知りたい場合があります。

于 2011-04-20T00:20:46.807 に答える
1

C#SerialPort.BytesToWriteプロパティは、次のように記述されているアンマネージ Win32COMSTAT.cbOutQueフィールドに対応します。

  • すべての書き込み操作で送信される残りのユーザー データのバイト数。重複しない書き込みの場合、この値はゼロになります。

これは、書き込み完了コールバックが呼び出される前に非同期書き込みで送信されるため、書き込みバッファーが消費されていることを確認できることを示唆しているようです。

于 2011-04-20T00:21:02.247 に答える
0

私は、0xAA をシリアル ポートから常にギャップなく送信するテスト ユーティリティを作成したいと考えていました。RXは関係ありません。

タイマーを使用してバッファーをいっぱいに保ち、BytesToWrite を監視して、バッファーにさらにデータを書き込む前に、しきい値を下回るまで待機しました。

別の方法として、タイマーを使用せずに AsyncCallback のシリアル ポートを更新することもできましたが、楽しみのためにこの方法でやりたかったのです。label11 を表示して、バッファーの塗りつぶしと空を確認できます。

EndWrite を使用せずに BeginWrite を使用しても、しばらくは問題なく使用できますが、最終的にはリソースが不足することに注意してください。私は基本的にダミーの EndWrite を入れています。

    private void checkBox2_CheckedChanged(object sender, EventArgs e)
    {
        timerFill.Enabled = checkBox2.Checked;
    }

    private void timerFill_Tick(object sender, EventArgs e)
    {
        GenerateSquareWave();
    }

    int const bufferSize = 256;

    void GenerateSquareWave()
    {
        int k = serialPort1.BytesToWrite;
        label11.Text = k.ToString();
        if (k < bufferSize)
        {
            byte[] data = new byte[bufferSize];
            for (int i = 0; i < bufferSize; i++)
            {
                data[i] = 0xAA;
            }
            serialPort1.BaseStream.BeginWrite(data, 0, data.Length, new AsyncCallback((IAsyncResult ar) => serialPort1.BaseStream.EndWrite(ar)), null);
        }
    }
于 2011-08-09T21:48:06.297 に答える