Shai
Shai

Reputation: 25619

Multiple BackgroundWorkers do not start work immediately

I'm trying to use BackgroundWorker to load-test a web service, Code is:

    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
    }

But according to the time taken for the job the get done, and according to the output of the workers (worker begin&end in the textbox), it takes way too long for each worker to start -

I would expect everything to run simultaneously, but instead, it executes only 2-3 background workers at a time...

Any ideas on this issue?

Upvotes: 2

Views: 1754

Answers (2)

MoonKnight
MoonKnight

Reputation: 23833

Giving some background to @Henk Holterman's correct answer that states the BackgroundWorker class uses the thread pool...

The thread pool starts out with one thread in it pool and the pool manager ‘injects' new threads to cope with extra asynchronous workload, upto some limiting maximum. After a set period of inactivity the pool manager may 'retire' threads if it 'thinks' that doing so will lead to a better throughput. In your case above the pool manager is limiting the number of concurrent threads.

You can set the upper limit on the number of threads the pool will create by calling Thread.Pool.SetMaxThread;, the defaults are:

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.

[_these figure may vary according to hardware and OS]. The reason for these vast number (at least in the case of .NET 4.0) is to ensure that progress is made even when some threads are blocked (running some intense work etc.)

You can set the lower limit via ThreadPool.SetMinThreads. The role of this limiter is more subtle than that of the max limiter: this instructs the pool manager not to delay the creation of threads until reaching this lower limit on number - setting this number as @Henk pointed out quite rightly will improve you concurrency when there are blocked threads.

I hope this helps.

Upvotes: 1

Henk Holterman
Henk Holterman

Reputation: 273179

Backgroundworkers run on top of the ThreadPool and the TP purposely limits the number of threads.

Since this is a Test(-driver) app there is no problem in changing the config of the Pool. You can set the Minimum number of threads to something sensible.

   ThreadPool.SetMinThreads(20, 20);

Upvotes: 3

Related Questions