我有以下代码:
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个并发线程命中数据库?
答案 0 :(得分:6)
BackgroundWorker
使用ThreadPool。您可以使用ThreadPool.SetMinThreads
和ThreadPool.SetMaxThreads
调整ThreadPool。如果实际上可以确定与数据库服务器的许多连接可能是另一个问题(并导致其他问题)。
但是,不建议启动500 BackgroundWorker
个实例! “任务并行库”可以通过Task类提供更好的解决方案。
答案 1 :(得分:1)
这样的事情应该会有所帮助:
Task.Factory.StartNew(
() => { SOME DB METHOD THAT TAKES 5 SECONDS },
TaskCreationOptions.LongRunning
);
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%合法。