[ad_1]
こんにちは。
C# アプリケーションを作成しました。
このプログラムには、UDP ソケット プロトコルからデータを受信し (5 ミリ秒ごと)、それらを 4 つの C# チャートにプロットするスレッドが含まれています。
このスレッドが開始されると、残念なことに、プログラムは大量のメモリと CPU 使用量を消費し始めます。
私が試したこと:
「ConcurrentQueue」クラスを使用すると問題は解決しますか?
この問題に関するあなたの提案は私を助けます!
注記:
不適切な英語ですみません!
編集:
ここから始まるスレッドがあります:
thRcv = new System.Threading.Thread(rcvDP);
thRcv.Start();
スレッドのメソッド:
internal void rcvDP() { while (!(RobotStat == 0 | RobotStat == 1)) { while (k_udpServer.Available > 0) { byte[] data = k_udpServer.Receive(ref ep_Server); if (!LogData_flag && SaveFileEnded_Log) { //recive_Data_Form(data); rcv_data_Form_Static(data); } else { rcv_Log_Data(data); } } } }
「rcv_data_Form_Static」は次のとおりです。
public void rcv_data_Form_Static(byte[] rcv_byte) { if (myFrmController.is_new_Trajectory) { my_Gait_Table.Time_Trajectory_Points = myFrmController.mGaitTable.Time_Trajectory_Points; my_Gait_Table.Trajectory_HL = myFrmController.mGaitTable.Trajectory_HL; my_Gait_Table.Trajectory_HL_dot = myFrmController.mGaitTable.Trajectory_HL_dot; my_Gait_Table.Trajectory_HR = myFrmController.mGaitTable.Trajectory_HR; my_Gait_Table.Trajectory_HR_dot = myFrmController.mGaitTable.Trajectory_HR_dot; my_Gait_Table.Trajectory_KL = myFrmController.mGaitTable.Trajectory_KL; my_Gait_Table.Trajectory_KL_dot = myFrmController.mGaitTable.Trajectory_KL_dot; my_Gait_Table.Trajectory_KR = myFrmController.mGaitTable.Trajectory_KR; my_Gait_Table.Trajectory_KR_dot = myFrmController.mGaitTable.Trajectory_KR_dot; myFrmController.is_new_Trajectory = false; } if (!firstDifinition) { #region new Definition firstDifinition = true; rcvMotorsEncoderData = new cMotorsEncoderData(); myPlot_HipLeft_Array = new Single[myDataArrayPlotNo + 1]; myPlot_KneeLeft_Array = new Single[myDataArrayPlotNo + 1]; myPlot_HipRight_Array = new Single[myDataArrayPlotNo + 1]; myPlot_KneeRight_Array = new Single[myDataArrayPlotNo + 1]; myPlot_HipLeft_Des_Array = new Single[myDataArrayPlotNo + 1]; myPlot_KneeLeft_Des_Array = new Single[myDataArrayPlotNo + 1]; myPlot_HipRight_Des_Array = new Single[myDataArrayPlotNo + 1]; myPlot_KneeRight_Des_Array = new Single[myDataArrayPlotNo + 1]; timeArray_Now = new float[myDataArrayPlotNo + 1]; timeArray = new float[myDataArrayPlotNo]; timeScale = 1000 / myDataArrayPlotNo; timeArrayFilled = false; PermitPlot = false; addRemoveCounter = 0; plotCounter = 0; array_PLotSync[0] = 0; array_PLotSync[1] = 0; #endregion for (int inn = 0; inn < 8; inn++) { pltSection[inn] = (int)(myDataArrayPlotNo * (inn + 1) / 8); } for (int m = 0; m < myDataArrayPlotNo; m++) { timeArray[m] = (int)(m * timeScale); } #region Plot Primary Trajectory try { InvokeDelegate InvokeFuncion = () => { try { for (int m = 0; m < myDataArrayPlotNo; m++) { timeArray[m] = (int)(m * timeScale); } } catch (Exception ex) { MessageBox.Show("in Invoke Plot" + ex.ToString()); } }; if (this.InvokeRequired) { BeginInvoke(InvokeFuncion); } else { Invoke(InvokeFuncion); } } catch (Exception ex) { MessageBox.Show("in Plot" + ex.ToString()); } #endregion } try { byte[] bytes_int = new byte[2]; byte[] bytes_single = new byte[4]; //Process codes int count = rcv_byte.Length; if (rcv_byte[0] == 0x0b && rcv_byte[count - 2] == 0x0c) { #region Data_receive int i = 1; // int hh = Convert.ToInt16(rcv_byte[i]); i++; //i=2 Int16 mm = Convert.ToInt16(rcv_byte[i]); //DATA_minute = mm; i++; //i=3 int ss = Convert.ToInt16(rcv_byte[i]); i++; //i=4 for (int j = 0; j < 2; j++) { bytes_int[j] = rcv_byte[i]; i++; } //i=5,i=6 int ms = BitConverter.ToInt16(bytes_int, 0); // #region FillMyClass_Rcv for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } //i=7,8,9,10 rcvMotorsEncoderData.LHip_pos = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.LKnee_pos = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.RHip_pos = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.RKnee_pos = BitConverter.ToSingle(bytes_single, 0); // for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.LHip_speed = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.LKnee_speed = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.RHip_speed = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.RKnee_speed = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.LHip2_pos = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.LKnee2_pos = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.RHip2_pos = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.RKnee2_pos = BitConverter.ToSingle(bytes_single, 0); // for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.LHip2_speed = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.LKnee2_speed = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.RHip2_speed = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.RKnee2_speed = BitConverter.ToSingle(bytes_single, 0); // for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.LHip_Torque = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.LKnee_Torque = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.RHip_Torque = BitConverter.ToSingle(bytes_single, 0); for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.RKnee_Torque = BitConverter.ToSingle(bytes_single, 0); // for (int j = 0; j < 4; j++) { bytes_single[j] = rcv_byte[i]; i++; } rcvMotorsEncoderData.Weight = BitConverter.ToSingle(bytes_single, 0); if (rcvMotorsEncoderData.Weight != 1) { if (!Eme_stop_message_showed) { BeginInvoke((InvokeDelegate)(() => { //this.Text = rcvMotorsEncoderData.Weight.ToString(); lbl_Error_Report.Text += "\nError Report: The Emergency stop is pressed! "; })); //MessageBox.Show("The Emergency stop is pressed!"); Eme_stop_message_showed = true; } } #region MotionLockWatch byte MotionLock = rcv_byte[i]; i++; if (MotionLock != 1) { // TreadmillOn = false; publicCounter = 999; #region everyTime_Want to ResetProgram try { try { InvokeDelegate InvokeFuncion = () => { try { if (!micro_switch_message_showed) { //MessageBox.Show("The micro switch is locked!"); lbl_Error_Report.Text += "\nError Report: The micro switch is locked!"; micro_switch_message_showed = true; } int ib = dgMessages.Rows.Count + 1; btnRunRobot.Text = "START"; // chkGaitAnalysis.Enabled = true; chkGaitAnalysis.Checked = false; btnSaveAnalyze.Enabled = true; cmd[0] = 0x06; // Header Byte cmd[1] = 0; //servo off cmd[2] = 0; cmd[3] = 0; cmd[4] = 6; SendCmdMainFrm(cmd); System.Threading.Thread.Sleep(70); if (RobotStat == 2) { thRcv.Abort(); k_udpServer.Close(); } RobotStat = 0; btnRunRobot.Enabled = false; chkGaitAnalysis.Enabled = false; btnSaveAnalyze.Enabled = false; chkServoOn.Enabled = true; btnSetZero.Enabled = false; } catch (Exception ex) { MessageBox.Show("in Invoke Run" + ex.ToString()); } }; if (this.InvokeRequired) { BeginInvoke(InvokeFuncion); } else { Invoke(InvokeFuncion); } } catch (Exception ex) { MessageBox.Show("Run" + ex.ToString()); } } catch (Exception en) { MessageBox.Show(en.ToString()); } /* this.Invoke((MethodInvoker)delegate { if (!micro_switch_message_showed) { MessageBox.Show("The micro switch is locked!"); micro_switch_message_showed = true; } }); */ #endregion everyTime_Want to ResetProgram } #endregion MotionLockWatch #endregion FillMyClass_Rcv #endregion Data_recive PermitPlot = true; TimeSpan Now = new TimeSpan(0, hh, mm, ss, ms); double Now_mod = Now.TotalSeconds % my_Gait_Table.Time_Trajectory_Points.Last(); safa_count = Convert.ToInt32(Now.TotalSeconds / my_Gait_Table.Time_Trajectory_Points.Last()); try { InvokeDelegate InvokeFuncion = () => { try { Gait_Abs_Error += Math.Abs(rcvMotorsEncoderData.LKnee_pos - InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_KL)) + +Math.Abs(rcvMotorsEncoderData.RKnee_pos - InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_KR)) + +Math.Abs(rcvMotorsEncoderData.LHip_pos - InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_HL)) + +Math.Abs(rcvMotorsEncoderData.RHip_pos - InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_HR)); chart1.Series["seri1"].Points.AddXY(Now.TotalSeconds, rcvMotorsEncoderData.LKnee_pos); chart1.Series["seri1n"].Points.AddXY(Now.TotalSeconds, InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_KL)); chart2.Series["seri2"].Points.AddXY(Now.TotalSeconds, rcvMotorsEncoderData.RKnee_pos); chart2.Series["seri2n"].Points.AddXY(Now.TotalSeconds, InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_KR)); chart3.Series["seri3"].Points.AddXY(Now.TotalSeconds, rcvMotorsEncoderData.LHip_pos); chart3.Series["seri3n"].Points.AddXY(Now.TotalSeconds, InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_HL)); chart4.Series["seri4"].Points.AddXY(Now.TotalSeconds, rcvMotorsEncoderData.RHip_pos); chart4.Series["seri4n"].Points.AddXY(Now.TotalSeconds, InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_HR)); /* chart1.Series["seri1"].Points.AddXY(Now_mod, rcvMotorsEncoderData.LKnee_pos); chart1.Series["seri1n"].Points.AddXY(Now_mod, InterpolatedVal(Now.TotalSeconds, Trajectory_KL)); chart2.Series["seri2"].Points.AddXY(Now_mod, rcvMotorsEncoderData.RKnee_pos); chart2.Series["seri2n"].Points.AddXY(Now_mod, InterpolatedVal(Now.TotalSeconds, Trajectory_KR)); chart3.Series["seri3"].Points.AddXY(Now_mod, rcvMotorsEncoderData.LHip_pos); chart3.Series["seri3n"].Points.AddXY(Now_mod, InterpolatedVal(Now.TotalSeconds, Trajectory_HL)); chart4.Series["seri4"].Points.AddXY(Now_mod, rcvMotorsEncoderData.RHip_pos); chart4.Series["seri4n"].Points.AddXY(Now_mod, InterpolatedVal(Now.TotalSeconds, Trajectory_HR)); */ if (safa_count != safa_count_1/*chart3.Series[0].Points.Count == 500*/) { safa_count_1 = safa_count; chart1.Series["seri1"].Points.Clear(); chart2.Series["seri2"].Points.Clear(); chart3.Series["seri3"].Points.Clear(); chart4.Series["seri4"].Points.Clear(); chart1.Series["seri1n"].Points.Clear(); chart2.Series["seri2n"].Points.Clear(); chart3.Series["seri3n"].Points.Clear(); chart4.Series["seri4n"].Points.Clear(); chart1.ChartAreas[0].AxisX.Minimum = Now.TotalSeconds; chart1.ChartAreas[0].AxisX.Maximum = Now.TotalSeconds + my_Gait_Table.Time_Trajectory_Points.Last(); chart2.ChartAreas[0].AxisX.Minimum = Now.TotalSeconds; chart2.ChartAreas[0].AxisX.Maximum = Now.TotalSeconds + my_Gait_Table.Time_Trajectory_Points.Last(); chart3.ChartAreas[0].AxisX.Minimum = Now.TotalSeconds; chart3.ChartAreas[0].AxisX.Maximum = Now.TotalSeconds + my_Gait_Table.Time_Trajectory_Points.Last(); chart4.ChartAreas[0].AxisX.Minimum = Now.TotalSeconds; chart4.ChartAreas[0].AxisX.Maximum = Now.TotalSeconds + my_Gait_Table.Time_Trajectory_Points.Last(); /* chart1.ChartAreas[0].AxisX.Minimum = 0; chart1.ChartAreas[0].AxisX.Maximum = 0 + my_Gait_Table.Time_Trajectory_Points.Last(); chart2.ChartAreas[0].AxisX.Minimum = 0; chart2.ChartAreas[0].AxisX.Maximum = 0 + my_Gait_Table.Time_Trajectory_Points.Last(); chart3.ChartAreas[0].AxisX.Minimum = 0; chart3.ChartAreas[0].AxisX.Maximum = 0 + my_Gait_Table.Time_Trajectory_Points.Last(); chart4.ChartAreas[0].AxisX.Minimum = 0; chart4.ChartAreas[0].AxisX.Maximum = 0 + my_Gait_Table.Time_Trajectory_Points.Last(); */ chart1.ChartAreas[0].AxisX.Interval = 1; chart2.ChartAreas[0].AxisX.Interval = 1; chart3.ChartAreas[0].AxisX.Interval = 1; chart4.ChartAreas[0].AxisX.Interval = 1; this.Text = Gait_Abs_Error.ToString(); if (Mogre_is_Running) { if (Gait_Abs_Error - Gait_Abs_Error_1 < -1.5) RuningMogre.quality_index_1 += 25; else if (Gait_Abs_Error - Gait_Abs_Error_1 > 1.5) RuningMogre.quality_index_1 -= 25; } Gait_Abs_Error_1 = Gait_Abs_Error; Gait_Abs_Error = 0; } } catch (Exception ex) { MessageBox.Show("in Invoke Plot" + ex.ToString()); } }; if (this.InvokeRequired) { BeginInvoke(InvokeFuncion); } else { Invoke(InvokeFuncion); } } catch (Exception ex) { MessageBox.Show("in Plot" + ex.ToString()); } #region Update thermometer parameter myFrmFlat_1.Abs_Error_KL = 0; myFrmFlat_1.Abs_Error_KR = 0; myFrmFlat_1.Abs_Error_HL = 0; myFrmFlat_1.Abs_Error_HR = 0; ////for (int ma = 0; ma < (int)mypltSection.eight; ma++) ////{ //// myFrmFlat_1.Abs_Error_KL += Math.Abs(myPlot_KneeLeft_Array[ma] - Trajectory_KL[ma]); //// myFrmFlat_1.Abs_Error_KR += Math.Abs(myPlot_KneeRight_Array[ma] - Trajectory_KR[ma]); //// myFrmFlat_1.Abs_Error_HL += Math.Abs(myPlot_HipLeft_Array[ma] - Trajectory_HL[ma]); //// myFrmFlat_1.Abs_Error_HR += Math.Abs(myPlot_HipRight_Array[ma] - Trajectory_HR[ma]); ///} // To know more about this next section go to "Main_Comments" region in frmFlat myFrmFlat_1.Abs_Error_KL_Final = myFrmFlat_1.Abs_Error_KL * 1.25; myFrmFlat_1.Abs_Error_HL_Final = myFrmFlat_1.Abs_Error_HL * 2.00; myFrmFlat_1.Abs_Error_KR_Final = myFrmFlat_1.Abs_Error_KR * 1.25; myFrmFlat_1.Abs_Error_HR_Final = myFrmFlat_1.Abs_Error_HR * 2.00; #endregion Update thermometer parameter #region Update_Mogre_Angles if (Mogre_is_Running == true) { RuningMogre.Mog_Hip_L = rcvMotorsEncoderData.LHip_pos; RuningMogre.Mog_Hip_R = rcvMotorsEncoderData.RHip_pos; RuningMogre.Mog_Knee_L = rcvMotorsEncoderData.LKnee_pos; RuningMogre.Mog_Knee_R = rcvMotorsEncoderData.RKnee_pos; } #endregion Update_Mogre_Angles #region Update_Flat_Form_Figure myFrmFlat.Required_data_left[0] = rcvMotorsEncoderData.LHip_pos; myFrmFlat.Required_data_left[1] = rcvMotorsEncoderData.LKnee_pos; myFrmFlat.Required_data_left[2] = InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_HL);// Trajectory_HL[plotCounter]; myFrmFlat.Required_data_left[3] = InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_KL);// Trajectory_KL[plotCounter]; myFrmFlat.Required_data_right[0] = rcvMotorsEncoderData.RHip_pos; myFrmFlat.Required_data_right[1] = rcvMotorsEncoderData.RKnee_pos; myFrmFlat.Required_data_right[2] = InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_HR);// Trajectory_HR[plotCounter]; myFrmFlat.Required_data_right[3] = InterpolatedVal(Now.TotalSeconds, my_Gait_Table.Trajectory_KR);// Trajectory_KR[plotCounter]; #endregion Update_Flat_Form_Figure plotCounter++; publicCounter = plotCounter; } } catch (Exception exc) { MessageBox.Show(exc.ToString() + "plotCounter = " + plotCounter.ToString()); } }
解決策 2
2 つのスレッドを使用します。
1 つはデータを「キャプチャ」するためのものです。
もう 1 つは、(配列またはリストから) 「キャプチャされた」データを読み取る「プロット」用です。
(独立して) 設計、構築、テストが容易になります。
タイマーを使用してプロットします。 100ms は「応答性」です。
[ad_2]
コメント