【发布时间】:2012-07-18 10:55:38
【问题描述】:
// procedural
foreach (var foo in bar)
{
foo.someProperty = getData(ref foo);
}
// threaded
foreach (var foo in bar)
{
ThreadStart work = delegate
{
getData(ref foo);
};
new Thread(work).Start();
}
getData(ref foo){
// Either a LINQ query
// Or Exec Command to Stored procedure in SQL Server
// Either taking approx 2 seconds to return results
foo.someProperty = resultsFromDBOrLinqStatement;
}
如果 bar 有 20 个项目,那么简单地使用程序 foreach 循环大约需要 10 秒 - 一个接一个地执行一个请求,每次都调用数据库。
如果对于相同的数据,使用每个循环的线程请求需要更长的时间?!看起来即使线程都很好,但来自每个线程的对 DB 的请求仍在阻止。
如果我将 getData() 方法修改为;
getData(ref foo){
thread.sleep(4000);
}
然后,正如预期的那样,整个请求在 4 秒内完成 - 所有线程几乎同时启动,并在 4 秒后同时退出。
我是否缺少与每个线程中的 DB 调用相关的东西,这会减慢整个过程的速度? - 一些用于与 DB 等并发连接的 web.config 设置?
PS。我尝试过并行 foreach 和 Tasks,但它总是回到线程与数据库调用一起减慢速度,就好像数据库服务器正在排队所有调用一样。
【问题讨论】:
-
你怎么知道所有的线程已经执行完毕才能测量时间?在您显示的代码的线程版本中,您只是启动线程但没有同步点。
-
每条 0.5 秒 - 相当慢 - 猜测 getData 正在执行相当数量的 SQL - 如果它在线程版本中较慢,您可能会遇到一些死锁
-
我目前有一个基本的监视器(在测试时),它在创建每个线程时递增一个线程计数器,并在每个线程调用 GetData 完成后递减计数器。
标签: c# asp.net-mvc .net-4.0