我制作了一个同时运行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。
答案 0 :(得分:2)
i5-6500有4个硬件线程,这意味着核心的使用得到了splittet并优化为4个线程。您可以在每个CPU上启动任意数量的踏板,但随后它们将运行如下: Singlecore示例:
开始A,停止A,开始b,停止b,再次开始,停止a,starb b 试。