我使用任务并行库(TPL)和C#4.5在Windows服务应用程序中实现此业务逻辑:
目前的问题是:将每个项目保存到数据库可能需要很长时间(同步DAL),因此Parallel.ForEach 1000项目将永远存在,并且Windows服务应用程序显得越来越慢。有没有人有好的想法或更好的方法来获得更好的表现?
代码段:
/* Download a list from RESTful API URL.... */
var task = Task.Factory.StartNew(() => { return DownloadListFromRestAPI(); }, TaskCreationOptions.LongRunning);
task.ContinueWith(i => {
foreach (var r in i.Result)
{
/* For each item, download the item details from RESTful API URL.... */
var taskSecond = Task.Factory.StartNew(() => { return DownloadItemDetailFromRestAPI(r.id); }, TaskCreationOptions.LongRunning);
taskSecond.ContinueWith(m => {
/* For each item detail, get the related business objects, and start Database operation on each object.... */
List<Item> relatedItems_1000 = s.GetRelatedObjectsIds(m.Result.id);
/* parallel.ForEach - 1000 or more items */
Parallel.ForEach<Item>(relatedItems_1000, new ParallelOptions { MaxDegreeOfParallelism = 8 }, d => DBLongProcess(d)); /* The DB operation takes long time */
});
}
});
更新:( DBLongProcess()的代码和锁(我添加了锁,因为并发线程可能会尝试将同一对象修改为DB))
private void DBLongProcess(Item item)
{
dbDAL.InsertObjectDB(item));
}
public class DBDAL
{
private readonly object _lock = new object();
public void InsertObjectDB(Item item)
{
lock (_lock)
{
if(!item.hasDetail1()){
//insert item.detail1...
}
if(!item.hasDetail2()){
//insert item.detail2
}
}
}
}
答案 0 :(得分:3)
在您的情况下,使用Parallel.ForEach()
不会加快任何速度,因为lock
中的InsertObjectDB()
会强制所有项目按顺序插入。
您需要做的是找出一种使DBDAL
线程安全的方法(可能通过使用它的多个实例)。如果这不可行,那么你必须在其他地方寻找性能改进。