C# 并行化考虑

C# 并行化考虑,c#,sql-server,multithreading,task-parallel-library,C#,Sql Server,Multithreading,Task Parallel Library,我想了解社区对此的看法。如果我有一个严重受DB/IO限制的进程,那么使用任务并行库并行化单个进程路径有多明智 我会用一个例子。。。如果我有一堆项目,我需要做以下操作 查询数据库中的项目列表 执行一些聚合操作,根据参数的动态列表对某些项进行分组 对于每个分组结果,根据聚合结果查询数据库中的内容 对于每个分组的结果,进行一些数值计算(3和4将按顺序进行) 对#3中计算的结果进行一些插入和更新 对#1中返回的每个项目进行插入和更新 从逻辑上讲,我可以在步骤#3、#5、#6并行化为一个任务图,因为一个项

我想了解社区对此的看法。如果我有一个严重受DB/IO限制的进程,那么使用任务并行库并行化单个进程路径有多明智

我会用一个例子。。。如果我有一堆项目,我需要做以下操作

  • 查询数据库中的项目列表
  • 执行一些聚合操作,根据参数的动态列表对某些项进行分组
  • 对于每个分组结果,根据聚合结果查询数据库中的内容
  • 对于每个分组的结果,进行一些数值计算(3和4将按顺序进行)
  • 对#3中计算的结果进行一些插入和更新
  • 对#1中返回的每个项目进行插入和更新
  • 从逻辑上讲,我可以在步骤#3、#5、#6并行化为一个任务图,因为一个项目与前一个步骤的结果没有关系。但是,这些都将在数据库(sql server)上等待,这很好,我知道我们只能在sql server允许的范围内进行处理

    但是我想在本地机器上逻辑地分配任务,以便它以数据库允许的速度处理任务,而不必等待任何结果。我做了一些模拟原型,用Thread.Sleeps替换db调用(我还尝试了.SpinWait的一些变体,速度快了一百万倍),并行版本比当前完全串行而非并行的实现快了很多


    我担心的是给SQL server带来太多压力。。。在我走这条路太远之前,我有什么考虑吗?p> 如果并行版本比串行版本快得多,我不会担心SQL server上的压力……当然,除非与DB server上执行的其他重要或时间关键的操作相比,您正在执行的任务优先级较低


    您对任务的描述我不太理解,但听起来似乎更多的任务应该直接在数据库中执行(我想可能有一些细节使得这不可能?

    如果并行版本比串行版本快得多,我不会担心SQL server的压力……当然,除非您正在执行的任务与在DB服务器上执行的其他重要或时间关键的操作相比优先级较低


    我不太理解您对任务的描述,但听起来这些任务中有更多应该直接在数据库中执行(我想有一些细节不可能做到这一点?)

    另一个选项是创建管道,以便第二组的步骤3与第一组的步骤4同时进行。如果可以在第5步重复更新,也可以这样做。通过这种方式,您可以执行并发SQL访问和处理,但不会使数据库负担过重,因为您一次只能执行两个并发操作

    因此,您按顺序执行步骤1和步骤2(我猜),以获得需要进一步处理的组集合。那么。主线程开始:

    for each group
      query the database
      place the results of the query into the calc queue
    
    第二个线程为结果队列提供服务:

    while not end of data
      Dequeue result from calc queue
      Do numeric calculations
      place the results of the query into the update queue
    
    第三个线程为更新队列提供服务:

    while not end of data
      Dequeue result from update queue
      Update database
    
    System.Collections.Concurrent.BlockingCollection
    对于这类事情来说是一个非常有效的队列

    这里的好处是,如果SQL Server可以处理更多并发事务,则可以通过添加多个计算线程或查询/更新线程来扩展它


    我在每日合并/更新程序中使用了与此非常类似的东西,结果非常好。该特定过程不使用SQL server,而是使用标准文件I/O,但概念转换得非常好。

    另一个选项是创建管道,以便第二个组的步骤3与第一个组的步骤4同时进行。如果可以在第5步重复更新,也可以这样做。通过这种方式,您可以执行并发SQL访问和处理,但不会使数据库负担过重,因为您一次只能执行两个并发操作

    因此,您按顺序执行步骤1和步骤2(我猜),以获得需要进一步处理的组集合。那么。主线程开始:

    for each group
      query the database
      place the results of the query into the calc queue
    
    第二个线程为结果队列提供服务:

    while not end of data
      Dequeue result from calc queue
      Do numeric calculations
      place the results of the query into the update queue
    
    第三个线程为更新队列提供服务:

    while not end of data
      Dequeue result from update queue
      Update database
    
    System.Collections.Concurrent.BlockingCollection
    对于这类事情来说是一个非常有效的队列

    这里的好处是,如果SQL Server可以处理更多并发事务,则可以通过添加多个计算线程或查询/更新线程来扩展它

    我在每日合并/更新程序中使用了与此非常类似的东西,结果非常好。这个特定的进程不使用SQL server,而是使用标准的文件I/O,但是这些概念转换得非常好