1

我有以下代码

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添加到其中。我应该如何重写它以确保安全?

4

1 回答 1

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 的重载,它提供本地状态以减少锁定频率,并将错误存储在本地状态中,然后在整个循环结束时聚合。我有一篇文章详细描述了有效聚合数据所需的过程Parallel.ForEach

于 2013-05-28T18:37:03.940 回答