我有以下代码
var myResponse = new Response();
Parallel
.ForEach(itemsListDto
, new ParallelOptions { MaxDegreeOfParallelism = 10 }
, itemDto => {
var tResponse = _itemService
.InsertItem
(itemDto
, new RequestMessage
{UserName = RequestUserName});
myResponse.AddErrors(tResponse.Errors);
}
);
return myResponse;
似乎myResponse
没有添加所有Errors
。我应该如何重写这个以确保安全?
答案 0 :(得分:4)
您需要同步myResponse
的访问权限,因为它听起来像AddErrors
方法不是线程安全的:
var myResponse = new Response();
var syncObj = new object();
Parallel.ForEach(itemsListDto, new ParallelOptions { MaxDegreeOfParallelism = 10 }, itemDto =>
{
var tResponse = _itemService.InsertItem(itemDto, new RequestMessage {UserName = RequestUserName});
lock(syncObj)
myResponse.AddErrors(tResponse.Errors);
});
return myResponse;
如果InsertItem
是一个相当漫长的过程,那么就性能而言这是可以接受的。
如果InsertItem
是一种相当快的方法,这可能会增加大量的同步开销,并导致总体时间接近同步循环。在这种情况下,您可能会使用Parallel.ForEach which provide local state的重载来减少锁定频率,并将错误存储在本地状态,然后在完整循环结束时进行聚合。我有一篇文章详细描述process required to aggregate data efficiently using Parallel.ForEach
。