【解決方法】大量のメモリと CPU 使用率を消費する C# プログラム

プログラミングQA

[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]

コメント

タイトルとURLをコピーしました