سؤال

I have the following code

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;

It seems that myResponse isn't getting all the Errors added to it. How should I rewrite this to be safe?

هل كانت مفيدة؟

المحلول

You would need to synchronize access to myResponse, since it sounds like the AddErrors method is not thread safe:

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;

If InsertItem is a fairly lengthy process, this may be acceptable in terms of performance.

If InsertItem is a fairly fast method, this may add a lot of synchronization overhead, and cause the overall time to approach a synchronous loop. In that case, you could potentially use the overloads of Parallel.ForEach which provide local state to lock less frequently, and store the errors in your local state, then aggregate at the end of the full loop. I have an article describing the process required to aggregate data efficiently using Parallel.ForEach in detail.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top