2013-05-28 37 views
1

我有以下代碼安全追加到列表中Parallel.ForEach

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

請發佈AddErrors的定義。 – Lee

回答

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

+0

我實現了Aggregation,效果很好,謝謝! – CaffGeek