###前提・実現したいこと
Queue にデータがあったのに、ゼロになってしまう現象にあった方がいらっしゃいましたら、
原因分析のアドバイスを頂ければと考えております。
###発生している問題・エラーメッセージ
Queue が空なのに Peek しているため、
「InvalidOprationException」が発生してしまいました。
###該当のソースコード
Program.cs class Program { volatile static bool _keyReaded = false; static void Main(string[] args) { ConvertFrame convertFrame = new ConvertFrame(); bool isFinish = false; while (!isFinish) { convertFrame.update(); Console.WriteLine(convertFrame.listFrames.Count.ToString()); /// キー入力で終了します。 if (_keyReaded) { isFinish = true; } } } static void MonitoringKey(object userState) { ConsoleKeyInfo keyInfo = Console.ReadKey(true); _keyReaded = true; } } ConvertFrame.cs class ConvertFrame { private Queue<byte> receivedDatas = new Queue<byte>(); private int backup_count = 0; public List<byte[]> listFrames { get; private set; } private Serial uart = new Serial(); public ConvertFrame() { listFrames = new List<byte[]>(); uart.Open("COM1", 115200); } public void update() { Queue<byte> pickedup = new Queue<byte>(); uart.getData(ref pickedup); if (pickedup.Count.Equals(0)) { return; } foreach( int index in Enumerable.Range(0, pickedup.Count ) ) { receivedDatas.Enqueue( pickedup.Dequeue() ); } if ( receivedDatas.Count.Equals(0) ) { return; } backup_count = receivedDatas.Count; // --- (1) byte head = receivedDatas.Peek(); //---- (2) head = 16; /// ---- (A) bool isExistDatas = true; while( isExistDatas ) { if ( receivedDatas.Count >= (int)head ) { List<byte> frame = new List<byte>(); foreach (int index in Enumerable.Range(0, (int)head )) { frame.Add(receivedDatas.Dequeue()); // ---(3) } listFrames.Add( frame.ToArray() ); } else { isExistDatas = false; } } } } Serial.cs class Serial { private SerialPort targetPort; private List<byte[]> receivedBytes = new List<byte[]>(); private byte[] pickedupBytes = new byte[4096]; public Serial() { } public void Open(string namePort, int baudRate) { string PortName = namePort; int BaudRate = baudRate; Parity Parity = Parity.None; int DataBits = 8; StopBits StopBits = StopBits.One; targetPort = new SerialPort(PortName, BaudRate, Parity, DataBits, StopBits); targetPort.Handshake = System.IO.Ports.Handshake.None; targetPort.ReadTimeout = 0; targetPort.WriteTimeout = 1500; targetPort.ReadBufferSize = 1024 * 12; targetPort.WriteBufferSize = 1024 * 12; targetPort.DataReceived += new SerialDataReceivedEventHandler(ReceivedHandler); targetPort.Open(); } public void Close() { targetPort.Close(); } public bool getData(ref Queue<byte> pickedup) { lock (receivedBytes) { if (receivedBytes.Count.Equals(0)) { return false; } foreach (byte[] array in receivedBytes) { foreach (byte data in array) { pickedup.Enqueue(data); } } /// 引数に渡したのでクリアする。 receivedBytes.Clear(); } return true; } private void ReceivedHandler(object sender, SerialDataReceivedEventArgs e) { int totalCount = 0; try { totalCount = targetPort.Read(pickedupBytes, totalCount, pickedupBytes.Length); } catch (TimeoutException exception) { Console.WriteLine(exception); Console.ReadKey(); } /// 固定長サイズのピックアップバッファから、受信データ数の分だけ取り出しておく。 byte[] buffer = new byte[totalCount]; Array.Copy(pickedupBytes, 0, buffer, 0, totalCount); lock (receivedBytes) { receivedBytes.Add(buffer); } return; } }
(2) で「InvalidOprationException」が発生し、ウォッチで確認すると、
確かに、receivedDatas.Count が ゼロ になっており、Peekでエラーなっていることは理解できるのですが、
直前の(1) backup_count は 0x20 とゼロではないため、
今後、どのような分析を行うべきか、質問させて頂きました。
追記:
問題の発生する部分だけ抽出してコード全体を書き直しました。
上記のコードを実際に走らせ、現象の再発を確認できしました。
ただ、今度は(3) で発生するようになりました。
このとき、backup_count = 0x36 , head = 0x06 なのですが、
例外で Queue が空という内容でした。
また、(A)の部分ですが、head の値が大きい場合に問題が発生している可能性も考えて、
16 byte に変更しています。だた、同じ例外が発生しました。
アドバイスの程、宜しくお願い申し上げます。
###補足情報(言語/FW/ツール等のバージョンなど)
visual studio 2013
.NET Framework 3.5
回答2件
あなたの回答
tips
プレビュー