我在i5 CPU上运行不超过4个线程?

时间:2017-11-16 08:16:21

标签: c# multithreading cpu hardware

我制作了一个同时运行5个线程的程序。这5个线程每个都将运行多个耗时的操作,总共可以持续约3个小时。

在2小时之前,UI似乎运行良好。但是我发现在大约2个小时过去之后,用户界面变得反应迟钝而且滞后。 此外,第5个线程的结果变得错误或具有虚假值。我已经尽力优化我的编码,但这仍然会发生。

我的公司计算机配有i5-6500 CPU和8 GB RAM。我在网上检查过这个CPU一次只能运行4个线程。要运行5个或更多线程,需要一个可以一次运行8个超线程的i7-7700。

我对这个硬件限制是对的吗?或者我可以用C#编码来解决这个问题吗?仅供参考,我正在使用BackgroundWorker处理我的多线程。

在向老板提议公司必须投资购买新CPU和主板之前,我必须确认这绝对是一个硬件问题。

非常感谢任何建议。 :)

private void Form1_Load(object sender, EventArgs e)
{
  using (StreamReader sr = new StreamReader(string.Concat(Directory.GetCurrentDirectory(), "\\limit.txt"), true))
       {
          String input; //read value limits from textfile and storing it in array
          int i = 1;
          while ((input = sr.ReadLine()) != null)
             {
                limit_memory[i]= input;
                i++;
             }
        }
    }

}
private void button1_Click(object sender, EventArgs e)
{
  //shows some textboxes that user has to fill and press enter to continue
}
private void button2_Click(object sender, EventArgs e)
{
  //shows some textboxes that user has to fill and press enter to continue
}
private void button3_Click(object sender, EventArgs e)
{
  //shows some textboxes that user has to fill and press enter to continue
}
private void button4_Click(object sender, EventArgs e)
{
  //shows some textboxes that user has to fill and press enter to continue
}
private void button5_Click(object sender, EventArgs e)
{
  //shows some textboxes that user has to fill and press enter to continue
}

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == '\r')
      {
        if (backgroundWorker1.IsBusy != true)
           {
              object[] button1_var = { sentry1, terminal1, txtBox1_serial};
              backgroundWorker1.RunWorkerAsync(button1_var); //pass some arguments with an object
           }
      }
}

private void textBox2_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == '\r')
      {
        if (backgroundWorker2.IsBusy != true)
           {
              object[] button2_var = { sentry2, terminal2, txtBox2_serial};
              backgroundWorker2.RunWorkerAsync(button2_var); //pass some arguments with an object
           }
      }
}
private void textBox3_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == '\r')
      {
        if (backgroundWorker3.IsBusy != true)
           {
              object[] button3_var = { sentry3, terminal3, txtBox3_serial};
              backgroundWorker3.RunWorkerAsync(button3_var); //pass some arguments with an object
           }
      }
}
private void textBox4_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == '\r')
      {
        if (backgroundWorker4.IsBusy != true)
           {
              object[] button4_var = { sentry4, terminal4, txtBox4_serial};
              backgroundWorker4.RunWorkerAsync(button4_var); //pass some arguments with an object
           }
      }
}
private void textBox5_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == '\r')
      {
        if (backgroundWorker5.IsBusy != true)
           {
              object[] button5_var = { sentry5, terminal5, txtBox5_serial};
              backgroundWorker5.RunWorkerAsync(button5_var); //pass some arguments with an object
           }
      }
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
  try
    {
      //uses the arguments passed and perform long operations
      //prints results to textFile1
    }
  catch
    {
      throw new BackgroundWorkerException(sernum, ex);//pass the unit's serial number to the error handler
    }
}
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
  try
    {
      //uses the arguments passed and perform long operations
      //prints results to textFile2
    }
  catch
    {
      throw new BackgroundWorkerException(sernum, ex);//pass the unit's serial number to the error handler
    }
}
private void backgroundWorker3_DoWork(object sender, DoWorkEventArgs e)
{
  try
    {
      //uses the arguments passed and perform long operations
      //prints results to textFile3
    }
  catch
    {
      throw new BackgroundWorkerException(sernum, ex);//pass the unit's serial number to the error handler
    }
}
private void backgroundWorker4_DoWork(object sender, DoWorkEventArgs e)
{
  try
    {
      //uses the arguments passed and perform long operations
      //prints results to textFile4
    }
  catch
    {
      throw new BackgroundWorkerException(sernum, ex);//pass the unit's serial number to the error handler
    }
}
private void backgroundWorker5_DoWork(object sender, DoWorkEventArgs e)
{
  try
    {
      //uses the arguments passed and perform long operations
      //prints results to textFile5
    }
  catch
    {
      throw new BackgroundWorkerException(sernum, ex);//pass the unit's serial number to the error handler
    }
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
  //updates the UI on what operations are being run
}
private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
  //updates the UI on what operations are being run
}
private void backgroundWorker3_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
  //updates the UI on what operations are being run
}
private void backgroundWorker4_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
  //updates the UI on what operations are being run
}
private void backgroundWorker5_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
  //updates the UI on what operations are being run
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  if (e.Cancelled == true) //if user cancels thread
    {
     //disconnect unit from PC, clears UI
    }
  else if(e.Error != null) //if error occurs in thread
    {
     string sernum = ((BackgroundWorkerException)e.Error).Sernum;
     //logs the serial number and error into a log text file
    }
  else //the program ends normally
    {
      //disconnect unit from PC, clears UI
    }
}
private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  if (e.Cancelled == true) //if user cancels thread
    {
     //disconnect unit from PC, clears UI
    }
  else if(e.Error != null) //if error occurs in thread
    {
     string sernum = ((BackgroundWorkerException)e.Error).Sernum;
     //logs the serial number and error into a log text file
    }
  else //the program ends normally
    {
      //disconnect unit from PC, clears UI
    }
}
private void backgroundWorker3_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  if (e.Cancelled == true) //if user cancels thread
    {
     //disconnect unit from PC, clears UI
    }
  else if(e.Error != null) //if error occurs in thread
    {
     string sernum = ((BackgroundWorkerException)e.Error).Sernum;
     //logs the serial number and error into a log text file
    }
  else //the program ends normally
    {
      //disconnect unit from PC, clears UI
    }
}
private void backgroundWorker4_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  if (e.Cancelled == true) //if user cancels thread
    {
     //disconnect unit from PC, clears UI
    }
  else if(e.Error != null) //if error occurs in thread
    {
     string sernum = ((BackgroundWorkerException)e.Error).Sernum;
     //logs the serial number and error into a log text file
    }
  else //the program ends normally
    {
      //disconnect unit from PC, clears UI
    }
}
private void backgroundWorker5_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  if (e.Cancelled == true) //if user cancels thread
    {
     //disconnect unit from PC, clears UI
    }
  else if(e.Error != null) //if error occurs in thread
    {
     string sernum = ((BackgroundWorkerException)e.Error).Sernum;
     //logs the serial number and error into a log text file
    }
  else //the program ends normally
    {
      //disconnect unit from PC, clears UI
    }
}
public class BackgroundWorkerException : Exception //to pass serial number to error handler
    {
        public string Sernum { get; set; }

        public BackgroundWorkerException(string sernum, Exception ex)

        {
            Sernum = sernum;
        }
    }

编辑:添加编码以显示我如何构建我的Backgroundworker。

1 个答案:

答案 0 :(得分:2)

i5-6500有4个硬件线程,这意味着核心的使用得到了splittet并优化为4个线程。您可以在每个CPU上启动任意数量的踏板,但随后它们将运行如下: Singlecore示例:

  

开始A,停止A,开始b,停止b,再次开始,停止a,starb b   试。