如何阻止BackgroundWorker排队?

时间:2013-07-02 13:42:10

标签: c# sql multithreading

我有以下代码:

for (int i = 1; i <= 500; i++)
{
    BackgroundWorker t = new BackgroundWorker();

    t.DoWork += SOME DB METHOD THAT TAKES 5 SECONDS
    t.RunWorkerAsync();
}

当我在SQL中对此进行分析时,我注意到BackgroundWorker似乎是以这样的方式对线程进行排队:只有4个或5个活动连接同时打开,而所有500个连接一次打开。我的数据库没有超时或阻止。如何防止此排队并同时使用所有500个并发线程命中数据库?

3 个答案:

答案 0 :(得分:6)

BackgroundWorker使用ThreadPool。您可以使用ThreadPool.SetMinThreadsThreadPool.SetMaxThreads调整ThreadPool。如果实际上可以确定与数据库服务器的许多连接可能是另一个问题(并导致其他问题)。

但是,不建议启动500 BackgroundWorker个实例! “任务并行库”可以通过Task类提供更好的解决方案。

答案 1 :(得分:1)

这样的事情应该会有所帮助:

Task.Factory.StartNew(
    () => { SOME DB METHOD THAT TAKES 5 SECONDS },
    TaskCreationOptions.LongRunning
);

来自MSDN documentation

  

LongRunning - 指定任务长时间运行,   粗粒度操作涉及更少,更大的组件   细粒度系统。它为TaskScheduler提供了一个提示   超额认购可能是有保证的。超额订阅可让您创建   比可用的硬件线程数更多的线程。


或者,您可以完全绕过线程池并直接使用Thread类:

var t = new Thread(() => { SOME DB METHOD THAT TAKES 5 SECONDS });
t.Start();

“Raw”线程比任务更难处理,但是......

答案 2 :(得分:0)

您没有,因为您的计算机不可能同时运行500个线程。最有可能的是,你有8到16个逻辑线程,4或5是你运行代码时可用的东西。似乎100%合法。