私の .Net コンソール アプリには、シリアル ポートに少数のバイト (約 20) を書き込み、応答を読み取る次のメソッドがあります (これも 20 バイト以下です)。これは、外部ハードウェア デバイスとの通信 (データの要求を送信し、要求された値を取得する) に使用されます。
余分なコード、ポートの初期化、変数の宣言などを切り取りましたが、それが何をしているかを見ることができます:-
var sw = new Stopwatch();
sw.Start();
// Write the "request" bytes.
_port.Write(buffer, 0, buffer.Length);
Console.WriteLine("After write: {0}", sw.ElapsedMilliseconds);
sw.Restart();
// Wait for response, but timeout after 100ms.
var timeoutCount = 0;
while (_port.BytesToRead == 0 && timeoutCount < 100)
{
Thread.Sleep(1);
timeoutCount++;
}
Console.WriteLine("Waited: {0}, #loops: {1}", sw.ElapsedMilliseconds, timeoutCount);
if (_port.BytesToRead == 0)
{
// Timed-out..
return null;
}
// Read the response.
var receivedData = new byte[_port.BytesToRead];
_port.Read(receivedData, 0, receivedData.Length);
return receivedData;
私のアプリは、タイトな (ほぼ継続的な) ループで上記のコードを呼び出します。いくつかのタイミングを出力するためにいくつかの Console.WriteLines を追加したことに気付くでしょう。次のような非常に一貫した数値が表示されます。
After write: 0 Waited: 14, #loops: 1 After write: 0 Waited: 14, #loops: 1 After write: 0 Waited: 14, #loops: 1 ...and so on...
while
明らかに、書き込みは非常に迅速に行われており、アプリがループを 1 回しか通過しないため、応答も迅速に到着していますThread.Sleep(1)
。
PC で別のウィンドウを開いたり、Chrome を実行したり、マウスを動かしたりすると、次のような数値が表示されます。
After write: 0 Waited: 4, #loops: 5 After write: 0 Waited: 2, #loops: 3 After write: 0 Waited: 2, #loops: 3 After write: 0 Waited: 1, #loops: 2 After write: 0 Waited: 3, #loops: 4
これは、私のようなシリアル ポート コードから期待されるものに似ており、PC が「アイドル」のときに見られる謎の 14 ミリ秒ではありません。何が起こっているかについてのアイデアはありますか?
私のアプリは100ミリ秒ごとに約12回の書き込み/読み取りを実行する必要があるため、問題が発生しています。2 番目の一連のタイミング (それぞれ数ミリ秒) から、これは簡単に達成できることがわかりますが、PC が「アイドル」の場合、各書き込み/読み取りに 14 ミリ秒かかるため、アプリで定期的にデータが失われます (これは外部で更新されます)。デバイスごとに 100 ミリ秒)。