启动每个BackgroundWorker数组元素之间的不需要的延迟

时间:2016-05-08 08:55:44

标签: c# multithreading parallel-processing backgroundworker

我想创建一个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个线程之间会有一段延迟。

2 个答案:

答案 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个线程仅适用于您的应用程序)。