【发布时间】:2014-06-09 12:01:07
【问题描述】:
我在 .Net 4.0 中工作,我的代码应该这样做:
我有一个向用户公开的 WebAPI。在这我有一个 Objects 的集合。基本上是一个包含一些对象的 ConcurrentBag 。我必须遍历此集合中的每个对象,然后在 Database 中插入/更新其数据。对象的数量可能很高(200-300)。除此之外,如果可以有多个并发用户使用我的 API。
现在,插入/更新非常慢,因为每条记录都会连接到数据库,这使得这个过程非常慢。不幸的是我不能改变这个逻辑。
为了提高性能,我使用了 Parallel.ForEach 而不是常规的 foreach,因为每次迭代都是不同的。另外,我正在为数据库中的每个插入创建一个单独的任务
这是我的代码
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 更好吗?
【问题讨论】:
-
" 对于每条记录,都会对数据库进行连接,这使得该过程非常缓慢" - 如果您使用常规 ADO.NET 连接到主要数据库,这听起来不太可能;通常开箱即用地支持自动连接池。目前这需要多少时间?我不确定
Parallel.ForEach是否在这里为您提供帮助(它甚至可能毫无帮助,即使情况变得更糟) -
所以这里发生的是当 SaveRecordingDetailsToDb 被调用时,它首先从 MongoDB 检索一些信息,然后在 MS SQL Server 中执行存储的过程。这是遗留代码:(
-
好吧,它的 SQL Server 部分应该支持连接池。我无法对 mongo 发表评论。回到问题:你有理由认为它可能导致某种泄漏吗?
-
通过使用数据库的批量插入机制,您可以获得更好的性能。从 MongoDB 中提取所有数据然后使用 SqlBulkCopy 将它们发送到服务器,或者将它们提取到磁盘然后使用 SSIS 处理和导入它们
-
Marc,我唯一担心的是我可能会产生很多线程,每个线程都会连接到 Mongo,然后是 SQL。如果为一个用户创建了 80-100 个线程,并且当有有很多并发用户,这会爆炸吗?
标签: c# .net multithreading task-parallel-library parallel.foreach