私のアプリケーションがシリアルに受信バイトを処理していましたが、私は奇妙なバグに気付きました。時にはバイト(いつも0x03になる)が2倍処理されて、なぜかわからない。c#は同じシリアル受信バイトを2回処理することがあります
バイトを受信すると、+= ReadExisting()
を使用して文字列に追加します。この文字列は私のバッファを形成します。バックグラウンドワーカーは、文字列が空になるまで文字列のすべてのバイトを処理します。文字列の最初の要素が読み込まれた後で削除されると、string.Length()
はループサイクルごとに小さな数値を返します。
private void serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
rxBuffer += serial.ReadExisting(); // adds new bytes to buffer
try { backgroundWorker1.RunWorkerAsync(); } catch { } // starts background worker if it is not working already.
}
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
while (rxBuffer.Length > 0)
{
byte b = Convert.ToByte(rxBuffer[0]); // reads in the next byte
rxBuffer = rxBuffer.Remove(0, 1); // deletes this byte from the string
// ... code ... does things do the UI and stuff
ループ2xの間にいくつかのシリアルバイトが実行されることは確かです。私は自分の成果でそれを見てきました。いくつかの理由から、ダブルバイトは常に0x03です。 rxBuffer
は、プログラムのどこにでも触れていないことに注意してください。
Bullseye set at (0,2)
2:05:10 << 0x80
2:05:10 << 0x3
2:05:10 << 0x13
Bullseye set at (1,2)
2:05:10 << 0x80
2:05:10 << 0x3
2:05:10 << 0x3 <--- this one should not be there.
Bullseye set at (3,0)
2:05:10 << 0x14
2:05:10 << 0x80
2:05:10 << 0x3
2:05:10 << 0x15
Bullseye set at (3,2)
2:05:10 << 0x80
2:05:10 << 0x3
2:05:10 << 0x16
Bullseye set at (4,2)
なぜこの問題が発生し、どうすれば解決できますか?それは非同期のバイト読み取りとバックグラウンドワーカーに関係していますか?
2つのスレッドでリソースを共有します。あなたは同期する必要があります。またはそれ以上:スレッドセーフバッファを使用します。 – Fildor
削除を実行しているときに読み取りイベントが発生している可能性があります。イベントが発生すると、インラインコードに干渉しないことを確認する必要があります。 – jdweng
これが本当にスレッディングの問題かどうかを調べるには、現在のスレッドIDとバッファの長さも出力してください。 – Fildor