Avatar billede dragnor Juniormester
21. november 2017 - 20:41 Der er 3 kommentarer og
2 løsninger

C# Parallel.ForEach(Folder folder in findFolderResults) hvordan?

Hej,

Pt. har jeg fået lavet en kode der løber alle mapper i en mailbox på Exchange server igennem.
Loopet sker med følgende kode:


ForEach(Folder folder in findFolderResults)

Det virker fint, men så næsnte nogen noget med flere tråde ved brug af Parallel.ForEach.

Men jeg kan simpelthen ikke finde ud af hvordan jeg skriver koden så Parallel.ForEach virker :-(

Noget der har styr på hvordan jeg evt. gør det?

På forhånd 1000 tak for hjælpen og din tid brugt på at hjælpe mig.
Avatar billede arne_v Ekspert
21. november 2017 - 21:06 #1
ForEach(Folder folder in findFolderResults)
{
    ...
}

->

Parallel.ForEach(findFolderResults, (folder) => {  ...  } );

Men du skal vaere sikker paa at ... koden er thread safe!!
Avatar billede dragnor Juniormester
21. november 2017 - 21:17 #2
thread safe???
Avatar billede arne_v Ekspert
21. november 2017 - 21:23 #3
At dem kan udfoeres parallelt i flere traade og stadig give det rigtige resultat.

Hvis traadene opdaterer de samme variable kan de komme til at overskrive hinandens resultater og dermed give et forkert resultat medmindre der tages skridt til at synkronisere.
Avatar billede arne_v Ekspert
21. november 2017 - 21:36 #4
Eksempel:


using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace E
{
    public class Program
    {
        public static void Main(string[] args)
        {
            int[] a = Enumerable.Range(1, 1000).ToArray();
            DateTime t1, t2;
            int sum;
            sum = 0;
            t1 = DateTime.Now;
            foreach(int a1 in a)
            {
                Thread.Sleep(10); // simulate lots of work
                sum += a1;
            }
            t2 = DateTime.Now;
            Console.WriteLine("single thread : result = {0} time = {1}", sum, (t2 - t1).TotalSeconds);
            sum = 0;
            t1 = DateTime.Now;
            Parallel.ForEach(a, (a1) =>
            {
                Thread.Sleep(10); // simulate lots of work
                sum += a1;
            });
            t2 = DateTime.Now;
            Console.WriteLine("multi thread : result = {0} time = {1}", sum, (t2 - t1).TotalSeconds);
            sum = 0;
            t1 = DateTime.Now;
            object mylock = new object();
            Parallel.ForEach(a, (a1) =>
            {
                Thread.Sleep(10); // simulate lots of work
                lock(mylock)
                {
                    sum += a1;
                }
            });
            t2 = DateTime.Now;
            Console.WriteLine("multi thread synched : result = {0} time = {1}", sum, (t2 - t1).TotalSeconds);
            Console.ReadKey();
        }
    }
}


Output:

single thread : result = 500500 time = 10.005
multi thread : result = 492573 time = 1.5079955
multi thread synched : result = 500500 time = 1.7003891

Det ses at multithreaded er betydeligt hurtigere end singlethreaded.

Men ogsaa at multithreaded uden synkronisering af adgangen til sum giver forkert resultat.
Avatar billede dragnor Juniormester
21. november 2017 - 21:48 #5
Tak, det giver rigtig god mening 🙂
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester