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

Unwanted delay between starting each BackgroundWorker array element

我想创建一组 BackgroundWorker,它们相互协同工作以利用多核处理器。假设我希望其中八个同时工作。我还想要一个单独的计时器线程在 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 个线程,则创建 16 个线程中的每一个线程之间都会有延迟,超过前 4 个线程。

我想,行 while (true) o.count += o.id; 消耗太多 CPU 其他操作可能会被阻止。

尝试在 o.count += o.id; 之前添加 Thread.Sleep(100); 或减少线程数(8 个线程 + GUI 线程 => 9 个线程仅适用于您的应用程序)。

I want them all to start straight away.

那么 Backgroundworkers 不是正确的工具。甚至 Windows 也可能不是正确的 OS。

ThreadPool 上的 Backgroundworkers 运行,准则是仅将其用于短时间(< 500 毫秒)任务。线程池以 2/秒(大约)的速度创建新线程。

简短的解决方案是增加 ThreadPool.Minthreads(查找实际的 name/method),但这仍然是一个古怪的解决方案。

您没有提供足够(真实)的信息以获得更好的建议。