C# 方法调用的多线程(从SQL Server检索数据)比过程版本慢
如果bar有20个项目,那么简单地使用过程性foreach循环大约需要10秒——执行一个又一个请求,每次调用DB 如果,对于相同的数据,每个循环使用线程,那么请求需要更长的时间?!看起来,即使所有线程都很好,但来自每个线程的对DB的请求仍在拖延时间 如果我将getData()方法修改为C# 方法调用的多线程(从SQL Server检索数据)比过程版本慢,c#,asp.net-mvc,.net-4.0,C#,Asp.net Mvc,.net 4.0,如果bar有20个项目,那么简单地使用过程性foreach循环大约需要10秒——执行一个又一个请求,每次调用DB 如果,对于相同的数据,每个循环使用线程,那么请求需要更长的时间?!看起来,即使所有线程都很好,但来自每个线程的对DB的请求仍在拖延时间 如果我将getData()方法修改为 // procedural foreach (var foo in bar) { foo.someProperty = getData(
// 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;
}
然后,正如预期的那样,整个请求在4秒钟内完成——所有线程几乎同时启动,并在4秒钟后并发运行并退出
每个线程中的DB调用是否遗漏了一些东西,从而使整个过程变慢了是否为数据库等的并发连接设置了一些web.config
另外,我已经尝试过并行foreach和Tasks,但它总是返回到线程化,数据库调用会减慢速度,就好像数据库服务器正在排队等待所有调用一样。当线程创建成本(时间、资源)增加时,多线程会产生效果小于过程执行时间的摘要。只有在满足以下所有条件时,对SQL server(或任何其他数据库服务器)的并行请求才会更快:
在任何其他情况下,只有一种方法可以使程序更快(除了获得更快的服务器,这并不总是可能的):通过减少服务器的工作量(使用存储过程、将结果缓存在临时表中、减少大型连接等)使每个请求本身更快.为了测量时间,您如何知道所有线程都已完成执行?在您所展示的代码的线程版本中,您只启动线程,但没有同步点。每小节0.5秒-相当慢-猜测getData正在执行相当多的SQL-如果线程版本中的速度较慢,您可能会遇到一些死锁,而我现在有一个基本的监视器(测试时)在创建每个线程时递增线程计数器,在每个线程调用GetData完成后递减计数器。
getData(ref foo){
thread.sleep(4000);
}