2

我正在尝试使用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 个后台工作人员......

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

4

2 回答 2

3

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

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

   ThreadPool.SetMinThreads(20, 20);
于 2012-07-04T08:41:46.233 回答
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 正确指出的那样设置这个数字会提高你的并发性有阻塞的线程。

我希望这有帮助。

于 2012-07-04T09:03:59.653 回答