question

TZacks-2728 avatar image
0 Votes"
TZacks-2728 asked DuaneArnold-0443 commented

How to populate and return List<T> from Parallel.ForEach using partitioning

See one example code

 namespace TaskPartitionExample
 {
     public partial class Form1 : Form
     {
         public Form1()
         {
             InitializeComponent();
         }
    
         private void button1_Click(object sender, EventArgs e)
         {
             List<Person> persons = GetPerson();
             int ageTotal = 0;
    
             Parallel.ForEach
             (
                 persons,
                 () => 0,
                 (person, loopState, subtotal) => subtotal + person.Age,
                 (subtotal) => Interlocked.Add(ref ageTotal, subtotal)
             );
    
             MessageBox.Show(ageTotal.ToString());
         }
    
         static List<Person> GetPerson()
         {
             List<Person> p = new List<Person>
             {
                 new Person() { Id = 0, Name = "Artur", Age = 5 },
                 new Person() { Id = 1, Name = "Edward", Age = 10 },
                 new Person() { Id = 2, Name = "Krzysiek", Age = 20 },
                 new Person() { Id = 3, Name = "Piotr", Age = 15 },
                 new Person() { Id = 4, Name = "Adam", Age = 10 }
             };
    
             return p;
         }
     }
    
     class Person
     {
         public int Id { get; set; }
         public string Name { get; set; }
         public int Age { get; set; }
     }
 }

I tried to change the above code to create new List<T> instance from init section of Parallel.Foreach and from body populate List<T> with data and from LocalFinally return the new list<T> but facing problem

             List<Person> persons1=new List<Person>();
             Parallel.ForEach(persons,new Person(), drow =>
                 {
    
                 },
                 (persons1)=> lock{}
             );


please help me to do it. i want to populate a list from parellel.foreach with data from another list. i want to create a local list<T> which i like to populate with data from my global List<T>. how it will be possible? How can i declare a local list with in parallel.foreach init section?
from body section i want to populate that local list with data from global List<T> and from Finally Block that want to return my local List<T> to outside. please guide me to achieve this.

Thanks

Edit

if i do it this way then what kind of problem i may face?

 var persons1 = new List<Person>();
 var locker = new object();
 Parallel.ForEach(
     persons,
     () => new List<Person>(), // initialize aggregate per thread 
     (person, loopState, subtotal) =>
     {
         subtotal.Add(person); // add current thread element to aggregate 
         return subtotal; // return current thread aggregate
     },
     p => // action to combine all threads results
     {
         lock (locker) // lock, cause List<T> is not a thread safe collection
         {
             persons1.AddRange(p);
         }
     }
 );


dotnet-csharp
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@TZacks-2728
Is there any problem with the current code? Or is the result not up to expectations?
If the result is wrong, could you please describe what the correct result should look like?

0 Votes 0 ·

Result is not wrong. i like to know can i use the above Parallel.ForEach in production? does the above code may overlap any value ?

0 Votes 0 ·

Maybe, you should do an integration test on the code before you move the code to a production environment.

0 Votes 0 ·

0 Answers