多个BackgroundWorkers无法立即开始工作

时间:2012-07-04 08:37:39

标签: c# multithreading backgroundworker

我正在尝试使用BackgroundWorker来加载测试Web服务, 代码是:

    private void button1_Click(object sender, EventArgs e)
    {
        CheckWS("11111");
        CheckWS("22222");
        CheckWS("3344111");
        // .. and some more of those, approx 1000
    }

    public void CheckWS(string sUser)
    {
        BackgroundWorker bgWork = new BackgroundWorker();

        bgWork.DoWork += new DoWorkEventHandler(bgWork_DoWork);

        sObject sData = new sObject();
        sData.iNum = iCount++;
        sData.sId = sUser;
        bgWork.RunWorkerAsync(sData);
    }

    public void bgWork_DoWork(object sender, DoWorkEventArgs e)
    {
        // Update a textbox that this worker started
        ...
        // Run a web service
        ...
        // Update the textbox as worker ended
    }

但是根据完成工作所花费的时间,并根据工人的输出(工人在文本框中开始和结束),每个工人开始需要太长时间 -

我希望一切都能同时运行,但相反,它一次只能执行2-3个后台工作人员......

关于这个问题的任何想法?

2 个答案:

答案 0 :(得分:3)

BackgroundWorkers在ThreadPool之上运行,TP故意限制线程数。

由于这是一个Test(-driver)应用程序,因此更改Pool的配置没有问题。您可以将最小线程数设置为合理的值。

   ThreadPool.SetMinThreads(20, 20);

答案 1 :(得分:1)

给@Henk Holterman的正确答案提供一些背景,说明BackgroundWorker类使用线程池......

线程池开始时池中有一个线程,池管理器“注入”新线程以应对额外的异步工作负载,最多限制一些。在一段时间不活动之后,池管理器可以“退出”线程,如果它“认为”这样做将导致更好的吞吐量。在您的情况下,池管理器限制并发线程数。

您可以通过调用Thread.Pool.SetMaxThread;来设置池将创建的线程数的上限,默认值为:

1023 in Framework 4.0 in a 32-bit environment.
32768 in Framework 4.0 in a 64-bit environment.
250 per core in Framework 3.5.
25 per core in Framework 2.0.

[_这些数字可能因硬件和操作系统而异]。这些数量巨大的原因(至少在.NET 4.0的情况下)是确保即使某些线程被阻塞(运行一些紧张的工作等)也会取得进展。

您可以通过ThreadPool.SetMinThreads设置下限。这个限制器的作用比最大限制器的作用更微妙:这指示池管理器不要延迟线程的创建,直到达到数字的下限 - 设置这个数字@Henk指出非常正确将提高你的并发性有阻塞的线程。

我希望这会有所帮助。