我想创建一个BackgroundWorkers数组,它们可以相互协作以利用多核处理器。让我们说我希望其中八个同时工作。我还想要一个单独的Timer线程在GUI中报告每个线程正在处理的一些数据。
我的问题是这个。每个工人开始工作大约需要3-4秒。所以数组中的第一个worker元素就会立即开始。第二次开始几秒钟后。第三个开始后几秒等等。
我希望他们都能马上开始。我该如何解决这个问题?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
BackgroundWorker[] bw;
int threads = 8;
data[] d;
private void Form1_Load(object sender, EventArgs e)
{
d = new data[threads];
for (int i = 0; i < threads; i++) d[i] = new data(i);
bw = new BackgroundWorker[threads];
for (int i = 0; i < threads; i++)
{
bw[i] = new BackgroundWorker();
bw[i].DoWork += new DoWorkEventHandler(Work);
}
timer1.Enabled = true;
for (int i = 0; i < threads; i++) bw[i].RunWorkerAsync(d[i]);
}
private void Work(object sender, DoWorkEventArgs e)
{
data o = (data)e.Argument;
while (true) o.count += o.id;
}
private void timer1_Tick(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
long total = 0;
for (int n = 0; n < threads; n++) {
sb.Append(d[n].id + ": " + d[n].count + "\n");
total+=d[n].count;
}
sb.Append("TOTAL: "+total);
richTextBox1.Text = sb.ToString();
}
}
public class data {
public int id;
public long count;
public data(int id)
{
this.id = id;
this.count = 0;
}
}
-------------------------------编辑:发现晚于3-4秒延迟仅适用于超出您拥有的最大逻辑核心数。所以,如果你有20个核心,并设置20个线程,这很好。但是,如果你有4个内核,并设置了20个线程,那么在创建超过前4个线程的16个线程之间会有一段延迟。
答案 0 :(得分:2)
我希望他们都能马上开始。
然后,Backgroundworkers不是正确的工具。也许甚至Windows都不是合适的操作系统。
后台工作者在ThreadPool上运行,指南仅用于短(<500ms)任务。 Threadpool以2 /秒(粗略)创建新线程。
简短的解决方案是增加ThreadPool.Minthreads(查找实际的名称/方法),但这仍然是一个糟糕的解决方案。
您没有提供足够的(真实)信息以获得更好的建议。
答案 1 :(得分:0)
我想,行while (true) o.count += o.id;
占用的CPU太多,可能会阻止其他操作。
尝试在Thread.Sleep(100);
之前添加o.count += o.id;
或减少线程数(8个线程+ GUI线程=&gt; 9个线程仅适用于您的应用程序)。