0
// 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 秒 - 一个接一个地执行一个请求,每次调用数据库。

如果对于相同的数据,使用每个循环的线程,请求需要更长的时间?!看起来即使线程都很好,对数据库的请求 - 来自每个线程 - 正在阻止事情。

如果我将 getData() 方法修改为;

getData(ref foo){

    thread.sleep(4000);
}

然后,正如预期的那样,整个请求在 4 秒内完成 - 所有线程几乎同时启动,并在 4 秒后同时退出。

我是否缺少与每个线程中的 DB 调用相关的东西,从而减慢了整个过程的速度?- 一些 web.config 设置用于与 DB 等的并发连接?

PS。我尝试过并行foreach和Tasks,但它总是回到线程与数据库调用减慢速度,就好像数据库服务器正在排队所有调用一样。

4

2 回答 2

0

只有满足以下所有条件,对 SQL 服务器(或任何其他数据库服务器)的并行请求才会更快:

  1. 服务器为每个传入请求提供一个空闲处理器内核(实际上每个请求使用一个线程)
  2. 每个传入的请求都涉及不同的文件(数据库、表......取决于实际的服务器)
  3. 每批文件(每个请求一个)位于自己的硬盘上
  4. 服务器有足够的可用物理内存来同时处理所有请求和所有涉及的数据
  5. 服务器进程不会耗尽内存(不太可能,但如果您请求大量数据,则在 32 位系统上......)

(如果您的服务器有 SSD,第 2 点和第 3 点无关紧要 - 在 SSD 上,并行和顺序读取多个文件的累积时间大致相同)

在任何其他情况下,您只有一种方法可以使您的程序更快(除了获得更快的服务器,这并不总是可能的):通过减少服务器的工作来使每个请求本身更快(使用存储过程,将结果缓存在临时表中,减少大连接...)。

于 2012-07-19T10:48:48.720 回答
0

当线程创建的成本(时间、资源)小于过程执行时间的汇总时,多线程会产生效果。

于 2012-07-19T10:01:34.507 回答