使用Parallel.ForEach和Tasks.Factory.StartNew进行数据库插入/更新

时间:2014-06-09 12:01:07

标签: c# .net multithreading task-parallel-library parallel.foreach

我在.Net 4.0工作,我的代码应该这样做:

我有一个向用户公开的WebAPI。在这里我有一个对象的集合。基本上是包含一些对象的ConcurrentBag。我必须遍历此集合中的每个对象,然后在数据库中插入/更新其数据。对象的数量可以很高(200-300)。除此之外,如果有多个并发用户使用我的API。

现在,插入/更新速度非常慢,因为对于每个记录,conn都是对数据库进行的,这使得这个过程非常慢。不幸的是,我无法改变这个逻辑。

为了提高性能,我使用Parallel.ForEach而不是常规foreach,因为每次迭代都是不同的。另外,我正在为db

中的每个插入创建一个单独的任务

这是我的代码

 var tasks = new List<Task>(allRecordings.Count);//Creating a Task List 
 Parallel.ForEach(allRecordings, recording =>
        {
            var recordingItem = recording;
            //Lines oF Code 
            //                                        

         if ( some Conditions){
          var task = Task.Factory.StartNew(
                               () => SaveRecordingDetailsToDb(ref recordingItem, device.Locale));
           recording.Title = recordingItem.Title;
           recording.ProgramId =recordingItem.ProgramId;
           recording.SeriesId = recordingItem.SeriesId;
           tasks.Add(task);//Adding Task to List
           }
         });
         Task.WaitAll(tasks.ToArray()); //Waiting for all Tasks to complete before going back to main   
                                          Function
}

当有多个并发请求使用此相同的API时,MemoryLeak是否会出现在上面的块中 此外,使用Parallel.ForEach将比普通的ForEach更好。

1 个答案:

答案 0 :(得分:0)

TPL(任务并行库)专为计算绑定操作而设计,适用于可以并行完成的操作(如在不同CPU内核上进行计算)。在你的情况下,你写入数据库,所以,基本上你写了一些东西到文件系统,即这是IO操作。在纯粹的并行性意义上,IO操作不能并行执行。如果同时运行多个IO操作,它们将简单地相互中断,因此与逐个运行它们相比,将花费更多时间来完成。当然,数据库服务器应该以某种方式处理这种情况,但它不会比逐个发送请求快得多,更可能的是,它会更慢。