IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

fonction recursive et parallelisme


Sujet :

C#

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2015
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mai 2015
    Messages : 5
    Par défaut fonction recursive et parallelisme
    Bonjour,
    jai une fonction ScanDir(string path, ref int Count)
    listant recursivement les repertoires.
    Cette fonction utilise un Parallel.Foreach
    dans laquelle est executée ScanDir(subdir, ref Count).
    Mais jai lerreur suivante:
    Cannot use ref or out parameter 'Count' inside an anonymous method, lambda expression, or query expression
    Une idée?

  2. #2
    Membre émérite Avatar de Momoth
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2013
    Messages
    318
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 318
    Par défaut
    Bonjour,

    Tu peux nous montrer le reste de ton code ?

    Est ce que par hasard tu utiliserais ton count dans une lambda expression dans ton ScanDir ?

  3. #3
    Nouveau membre du Club
    Femme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2015
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mai 2015
    Messages : 5
    Par défaut
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    public static bool RecursiveScan3(string DirPath, string RootPath, ConcurrentStack<XDocument> liste, int NbItemsPerItem, myParameterObject o, XElement ParentElement, int DirIndex)
            {
                bool bFail = false;
                List<DirectoryElement> listeDirectories = new List<DirectoryElement>();
                IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
                WIN32_FIND_DATAW findData;
                IntPtr findHandle = INVALID_HANDLE_VALUE;
     
                try
                {
                    findHandle = FindFirstFileW(DirPath + @"\*", out findData);
                    if (findHandle != INVALID_HANDLE_VALUE)
                    {
                        do
                        {
                            if (findData.cFileName == "." || findData.cFileName == "..") continue;
     
                            if (NbItemsPerItem > 0)
                            {
                                if (o.Count > NbItemsPerItem - 1)
                                {
                                    XDocument xml =
                                    new XDocument(
                                        new XElement("item", new XAttribute("name", ""), new XAttribute("isDir", "1"))
                                    );
                                    liste.Push(xml);
                                    o.Count = 0;
                                    ParentElement = null;
                                }
                            }
                            bool isDir = ((findData.dwFileAttributes & FileAttributes.Directory) != 0);
     
                            long size = -1;
                            if (!isDir)
                                size = (long)findData.nFileSizeLow + (long)findData.nFileSizeHigh * 4294967296;
     
                            string fullpath = DirPath + @"\" + findData.cFileName;
                            string itemPath = "";
                            if (ParentElement == null)
                                itemPath = fullpath.Replace(RootPath, "").Replace(@"\", "/");
                            else
                            {
                                if ((liste.Count - 1) != DirIndex)
                                    ParentElement = null;
                            }
     
                            XElement ParentElementReturned = GenerateNodeFromPath4(liste.ToArray()[0], ParentElement, itemPath, findData.cFileName, isDir, size);
     
                            o.Count++;
                            if (isDir)
                            {
                                listeDirectories.Add(new DirectoryElement(fullpath, ParentElementReturned, liste.Count - 1));
                            }
                        }
                        while (FindNextFile(findHandle, out findData));
                    }
                }
                finally
                {
                    if (findHandle != INVALID_HANDLE_VALUE) FindClose(findHandle);
                }
     
     
                Parallel.ForEach(listeDirectories,
                    (dir, loopState) =>
                    {
                        if (!RecursiveScan3(dir.Path, RootPath, liste, NbItemsPerItem, o, dir.Elt, dir.XmlIndex))
                        {
                            bFail = true;
                            loopState.Stop();
                        }
                    }
                );
     
                return !bFail;
            }

  4. #4
    Membre émérite Avatar de Momoth
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2013
    Messages
    318
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 318
    Par défaut
    Utilise les balises CODE la prochaine fois, s'il te plait, c'est plus lisible.

    Perso avec ton code, je n'ai aucun problème de compilation. Et ta méthode est quand même bien différente de celle de ton premier post.

  5. #5
    Membre Expert
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Par défaut
    Bonjour,

    Juste une question pour que je comprenne : Tu es obligée d'utiliser les api Windows plutôt que les methodes du framework comme Directory.GetFiles(...) ? Ce serait quand même plus simple...

  6. #6
    Nouveau membre du Club
    Femme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2015
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mai 2015
    Messages : 5
    Par défaut
    Oui pour des soucis de perf, pour des répertoires de millions de fichiers, c la meilleure solution. Jai tout testé et comparé. Mais mon souci n'est pas la.
    Ca a l'air de bien fonctionner pour de petits répertoires, ca ma genere une liste de XML contenant au max N noeuds.
    Mais pour des plus gros (des millions de fichiers), ca gele mon application... Une idée?

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
     
    DateTime startTime = DateTime.Now;
    Console.WriteLine("\n\rFunction Scan starts at " + startTime.ToString("HH:mm:ss") + "...");
    ConcurrentStack<XDocument> listeXml = new ConcurrentStack<XDocument>();
    XDocument xml =
                new XDocument(
                    new XElement("item", new XAttribute("name", ""), new XAttribute("isDir", "1"))
                );
                listeXml.Push(xml);
                if (CifsFunctions.ListFiles3(@"\\192.168.6.152\360store\FOOK\SOURCE\TestArchive\ARCHIVE 1", @"\\192.168.6.152\360store\FOOK\SOURCE", "spark", "spark", "", listeXml, NbItemsPerRequest))
                {
                    Console.WriteLine("File list retrieved in " + DateTime.Now.Subtract(startTime).ToString(@"hh\:mm\:ss"));
                    for (int i = listeXml.Count - 1; i >= 0; i--)
                    {
                        int Nb = listeXml.ToArray()[i].Root.Descendants("item").Where(x => (string)x.Attribute("isDir") == "1").Count() - 1;
                        int Nb2 = listeXml.ToArray()[i].Root.Descendants("item").Where(x => (string)x.Attribute("isDir") == "0").Count();
                        Console.WriteLine("Nb Directories =  " + Nb.ToString() + " / Nb Files = " + Nb2.ToString());
                    }
                }
                return true;
    }
     
     
    public static bool ListFiles3(string DirPath, string RootPath, string WinLogin, string WinPassword, string Domain, ConcurrentStack<XDocument> liste, int NbItemsPerItem)
            {
                bool bFail = false;
                string errMsg = "";
                int errorCode = 0;
     
                bool bConnected = Directory.Exists(DirPath);
                if (!bConnected)
                {
                    if (CifsFunctions.ConnectToSharedFolder(Domain, DirPath, WinLogin, WinPassword, out errorCode, out errMsg))
                    {
                        bConnected = Directory.Exists(DirPath);
                    }
                }
                if (bConnected)
                {
                    myParameterObject o = new myParameterObject(0);
                    if (!RecursiveScan3(DirPath, RootPath + @"\", liste, NbItemsPerItem, o, null, liste.Count - 1))
                    {
                        bFail = true;
                    }
                }
                else
                {
                    bFail = true;
                }
                return (!bFail);
            }
     
    private static XElement GenerateNodeFromPath4(XDocument doc, XElement ParentElt, string itemPath, string itemName, bool isDir, long size)
            {
                XElement ParentEltReturned = null;
                if (ParentElt == null)
                {
                    string[] items = itemPath.Split(Delimiter);
                    ParentElt = doc.Root;
                    XElement elt;
                    for (int i = 0; i < items.Length - 1; i++)
                    {
                        elt = ElementExists2(ParentElt, items[i], "", true);
                        if (elt == null)
                        {
                            XElement el = new XElement("item");
                            el.SetAttributeValue("name", items[i]);
                            el.SetAttributeValue("isDir", "1");
                            ParentElt.Add(el);
                            ParentElt = el;
                        }
                        else
                        {
                            ParentElt = elt;
                        }
                    }
                }
     
                ParentEltReturned = ParentElt;
     
                if (isDir)
                {
                    XElement el = new XElement("item");
                    el.SetAttributeValue("name", itemName);
                    el.SetAttributeValue("isDir", "1");
                    ParentElt.Add(el);
                    ParentEltReturned = el;
                }
                else
                {
                    string filenameWithoutExt;
                    string fileExt;
                    int idx = itemName.LastIndexOf('.');
                    if (idx >= 0)
                    {
                        filenameWithoutExt = itemName.Substring(0, idx);
                        fileExt = itemName.Substring(idx + 1);
                    }
                    else
                    {
                        filenameWithoutExt = itemName;
                        fileExt = "";
                    }
     
                    XElement el = new XElement("item");
                    el.SetAttributeValue("ext", fileExt);
                    el.SetAttributeValue("name", filenameWithoutExt);
                    el.SetAttributeValue("isDir", "0");
                    if (size >= 0)
                        el.SetAttributeValue("size", size);
                    ParentElt.Add(el);
                }
                return ParentEltReturned;
            }

    Quand NbItemsPerRequest = 0, ca me sort un gros xml en 53 s (800 000 fichiers, 150 000 folders).
    En revanche, quand je veux faire des lots de NbItemsPerRequest = 10 000, ca me bloque mon appli.

Discussions similaires

  1. [C#] probleme avec une fonction recursive
    Par K_!!! dans le forum ASP.NET
    Réponses: 2
    Dernier message: 01/08/2006, 18h22
  2. [Debutante] Fonction recursive avec un pointeur
    Par kidney dans le forum Débuter
    Réponses: 9
    Dernier message: 25/03/2006, 08h08
  3. Réponses: 3
    Dernier message: 22/12/2005, 11h20
  4. [XSL]Probleme fonction recursive
    Par Le-Cortex dans le forum XSL/XSLT/XPATH
    Réponses: 9
    Dernier message: 12/12/2005, 15h10
  5. probleme sql, fonction recursive
    Par CaptainChoc dans le forum Langage SQL
    Réponses: 2
    Dernier message: 21/11/2005, 01h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo