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 :

Traitement Excel dans C#, plantage mémoire


Sujet :

C#

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2009
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 194
    Points : 102
    Points
    102
    Par défaut Traitement Excel dans C#, plantage mémoire
    Bonjour à tous.

    Je travaille sur une application C#que je n'ai aps developpé moi-même.
    Cette appli fait tout un tas de chose, et particulierement des traitements sur fichiers Excel. Mais de très gros fichiers Excel, facilement quelques dizaine de milliers de lignes sur plusieurs dizaines de colonnes. Avec en plus, plusieurs sheet, avec ces fameuse lignes et colonnes.

    On a finit par me remonter des problèmes de plantage apparement dû à la taille des ces fichiers. En voulant reproduire les bugs, j'ai eu plusieurs type d'erreur :

    - Out of memory

    Au bout d'un moment de traitement, un pop up apparait et me balance un outofMemory Exception. C'est l'erreur la plus difficile à reproduire, car d'une part aléatoire, d'autre part ce sont souvent les autres bugs qui apparaissent avant.
    Cette exception apparait toujours l'un d'un traitement de gros fichiers Excel, parfois 500k lignes.

    - COM class factory et plein de thread Excel

    L'erreur la plus courante.
    Pendant le traitement, je vois beaucoup de task Excel qui se créées dans mon task manager.
    Nom : excel_task.png
Affichages : 424
Taille : 29,9 Ko
    Et il peu même parfois y en avoir plus.

    Du coup à un moment donné j'ai un "Excel a cessé de fonctionner", puis l'appli stop son traitement avec
    Nom : excel_popup.png
Affichages : 342
Taille : 19,2 Ko



    Ayant un peu regardé sur le net les problèmes de mémoire, je n'ai trouvé que des soucis en 32 bit, je suis en 64, je ne pense pas que ça vienne de là.
    Mais je ne trouve nul part traces de souci de cet ordre avec du C# ou du traitement Excel. Du coup je ne sais pas bien quoi faire...

    Je sais que dans le code, chaque ligne peut devenir un objet, et que ces objets peuvent être clonés, voire plusieurs fois. Mais j'ai du mal à penser que C# ne puisse gérer ça.
    De plus, le plantage se fait après la mise en mémoire des Excel dans l'appli, j'ai du mal à faire le lien entre les thred Excel, alors que tout est supposé être chargé dans des tableaux/objets.

    Merci de votre aide.

  2. #2
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    Si on lance 50 Excels que se soit en vbs, bat ou c# on risque d'avoir des soucis de mémoire évident.

    Le nombre de ligne colonne n'est pas très impressionnant. Ça ne devrait pas poser de problème après je ne sais pas quel traitement sont effectué dans Excel.

    Le programme as il réellement besoin de lancer autant d'instance d'Excel ? Pour moi c'est soit :
    - un bug
    - un gros soucis d'optimisation (oublie de fermer l'Excel qui vient d'être utilisé ...)

  3. #3
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 904
    Points : 10 168
    Points
    10 168
    Billets dans le blog
    36
    Par défaut
    Bonjour,

    Excel a un très gros problème. Il doit avoir constamment tout le classeur en mémoire vive pour fonctionner. Excel 64 est moderne et peut utiliser la mémoire disponible sur un ordinateur 64 bits. Excel à 32 bits est une antiquité incapable d'adresser la totalité de la mémoire d'un système à 64 bits.

    Ceci dit, tu ne nous dis pas le plus important. Comment accèdes-tu à ton classeur Excel ? Si je me fie à tes images, tu le fais avec les bibliothèques Interop (PIAs).

    Il existe des façons d'accéder directement au fichier, de créer et modifier un fichier Office (2007 et suivants) sans même avoir Excel sur la machine. Mais là, je suis trop fainéant pour réécrire ce que je viens presque juste d'écrire.

    http://www.developpez.net/forums/d15...l/#post8578427
    À ma connaissance, le seul personnage qui a été diagnostiqué comme étant allergique au mot effort. c'est Gaston Lagaffe.

    Ô Saint Excel, Grand Dieu de l'Inutile.

    Excel n'a jamais été, n'est pas et ne sera jamais un SGBD, c'est pour cela que Excel s'appelle Excel et ne s'appelle pas Access junior.

  4. #4
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 195
    Points
    5 195
    Par défaut
    Salut

    evidemment, réécrire ton application est peut-être un brin compliqué mais j'aurais tendance à utiliser une librairie type EEplus pour jouer avec mes fichiers
    EXcel...

    Après, la multitude d'Excel ouvert, ça ressemble à des Task lancées en parallèle et qui chacune ouvre le bazar... donc, forcément, si chaque Task ouvre
    un excel pour travailler sur une partie du document, c'est pas du tout optimisé...

    Sachant que la "logique" voudrait qu'on ouvre une fois le document et qu'on utilise éventuellement des taches (task) pour travailler sur des parties différentes,
    non liées dans le traitement
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2009
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 194
    Points : 102
    Points
    102
    Par défaut
    Merci à tous d'avoir pris le temps de réflechir à mon problème.

    Alors je suis sur un sytème 64bit et effectivement, les bibliothèques utilisées sont les Interop (Icrosoft.Office.Interop...).
    J'ai eu également un peu de temps pour regarder ce qui avait été fait, et je n'aurai malheuresement aps le temps de refaire tout ce qui a été fait, avec une autres API.

    Après investigation, il semble effectivement que l'appli ouvre plusieurs Excel pour traiter différentes parties du document, et ne referme pas ces parties.
    Je suis tombé sur ce site : https://www.add-in-express.com/creat...l-com-objects/
    Qui explique qu'il faut fermer les objets COM. J'ai bien essayé, mais ça ne fonctionne pas du tout...

    Voilà ce que eux préconise:
    Code : 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
    Excel.Application app = null;
    Excel.Workbooks books = null;
    Excel.Workbook book = null;
    Excel.Sheets sheets = null;
    Excel.Worksheet sheet = null;
    Excel.Range range = null;
     
    try
    {
        app = new Excel.Application();
        books = app.Workbooks;
        book = books.Add();
        sheets = book.Sheets;
        sheet = sheets.Add();
        range = sheet.Range["A1"];
        range.Value = "Lorem Ipsum";
        book.SaveAs(@"C:\Temp\ExcelBook" + DateTime.Now.Millisecond + ".xlsx");
        book.Close();
        app.Quit();
    }
    finally
    {
        if (range != null) Marshal.ReleaseComObject(range);
        if (sheet != null) Marshal.ReleaseComObject(sheet);
        if (sheets != null) Marshal.ReleaseComObject(sheets);
        if (book != null) Marshal.ReleaseComObject(book);
        if (books != null) Marshal.ReleaseComObject(books);
        if (app != null) Marshal.ReleaseComObject(app);
    }
    Voila ce que j'avais moi
    Code : 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
     public static object[,] ReadFile(string filepath, string sheetname)
            {
                Application xlApp = null;
                Workbook wb = null;
                object[,] values = null;
                try
                {
                    xlApp = new ApplicationClass();
                    wb = xlApp.Workbooks.Open(filepath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
                    Worksheet sh = (Worksheet)wb.Worksheets.get_Item(sheetname);
     
                    values = sh.UsedRange.Value2 as object[,];
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Sheet \"{0}\" does not exist in the Excel file", sheetname));
                }
                finally
                {
                    if (wb != null)
                       wb.Close(false, missing, missing);
     
                    if (xlApp != null)
                        xlApp.Quit();              
                }
     
                return values;
            }
    Et voila ce que j'ai éssayé de rajouter :

    Code : 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
     public static object[,] ReadFile(string filepath, string sheetname)
            {
                Application xlApp = null;
                Workbook wb = null;
                object[,] values = null;
                try
                {
                    xlApp = new ApplicationClass();
                    wb = xlApp.Workbooks.Open(filepath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
                    Worksheet sh = (Worksheet)wb.Worksheets.get_Item(sheetname);
    
                    values = sh.UsedRange.Value2 as object[,];
                    if (sh != null) Marshal.ReleaseComObject(sh);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Sheet \"{0}\" does not exist in the Excel file", sheetname));
                }
                finally
                {
                    /*                if (wb != null)
                                        wb.Close(false, missing, missing);
                     */
                    if (xlApp != null)
                        xlApp.Quit();
    
                  if (wb != null) Marshal.ReleaseComObject(wb);
                    
                }
    
                return values;
            }
    Malheuresement ça ne fonctionne pas, ça ne ferme rien du tout.
    Mais ça fait sens avec ce que vous disiez tous.

  6. #6
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    J'ai vérifier effectivement le process excel ne se ferme pas.
    Sauf avec ça même si c'est déconseiller de forcer la collecte du ramasse miette.
    http://www.craigmurphy.com/blog/?p=82

    J'avait eu le même soucis avec l'objet COM IE.

    Je rejoint donc l'avis de theMonz31.
    Il vaut mieux une seul instance d'Excel, qui fasse les opérations plutôt que de la fermer/rouvrir.
    Je ne pense pas que ton logiciel fasse du parallélisme.

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2009
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 194
    Points : 102
    Points
    102
    Par défaut
    Le problème en killant toutes les tasks Excel, c'est que si l'utilisateur à une autre feuille Excel de lancée, ça va la fermer.

    Je vais essayer de ne faire ouvrir le workbook qu'une seule fois, et je reviendrai annoncer le resultat.

  8. #8
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    Non en faite je ne parlais pas de killer, j'auri du préciser il se ferme correctement avec ça:

    Code : 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
      Marshal.ReleaseComObject(excelWorksheet);  
      Marshal.ReleaseComObject(excelSheets);  
      Marshal.ReleaseComObject(excelWorkbooks);  
      Marshal.ReleaseComObject(excelWorkbook);  
      Marshal.ReleaseComObject(excelApp);  
     
      excelWorksheet = null;  
      excelSheets = null;  
      excelWorkbooks = null;  
      excelWorkbook = null;  
      excelApp = null;  
     
      GC.GetTotalMemory(false);  
      GC.Collect();  
      GC.WaitForPendingFinalizers();  
      GC.Collect();  
      GC.GetTotalMemory(true);

  9. #9
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2009
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 194
    Points : 102
    Points
    102
    Par défaut
    Je reviens finalement sur cette discussion, sans avoir trouvé de solution. En effet j'ai testé trois choses differentes mais avec les même résultats...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (sh != null)
                    {
                        Marshal.ReleaseComObject(sh);
                        sh = null;
                    }
    Qui consiste à "libérer" les objets COM, si j'ai bien compris.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Application xlApp = null;
                Workbooks wks = null;
                Workbook wb = null;
                Sheets sheets = null;
                Worksheet sh = null;
                object[,] values = null;
     
                    xlApp = new ApplicationClass();
                    wks = xlApp.Workbooks;
                    wb = wks.Open(filepath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);   
                    sheets = wb.Worksheets;
                    sh = (Worksheet)sheets.get_Item(sheetname);
    Le "not-two-dot" access aux objets, afin de ne pas créer de CWR ou quelque chose du genre, la j'avoue ne pas avoir tout compris...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    GC.GetTotalMemory(false);
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    GC.Collect();
                    GC.GetTotalMemory(true);
    Et la solution de mon VDD consistant à vider la mémoire.

    Ces trois solutions ne fonctionnent pas. Voici le code de la fonction :

    Code : 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
         public static object[,] ReadFile(string filepath, string sheetname)
            {
                Application xlApp = null;
                Workbooks wks = null;
                Workbook wb = null;
                Sheets sheets = null;
                Worksheet sh = null;
                object[,] values = null;
                try
                {
                    xlApp = new ApplicationClass();
                    wks = xlApp.Workbooks;
                    wb = wks.Open(filepath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);   
                    sheets = wb.Worksheets;
                    sh = (Worksheet)sheets.get_Item(sheetname);
     
                    values = sh.UsedRange.Value2 as object[,];
     
     
     
     
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Sheet \"{0}\" does not exist in the Excel file", sheetname));
                }
                finally
                {
                  /*  if (wb != null)
                        wb.Close(false, missing, missing);
     
                    if (xlApp != null)
                        xlApp.Quit();
    */
                    if (sh != null)
                    {
                        Marshal.ReleaseComObject(sh);
                        sh = null;
                    }
     
                    if (wb != null)
                    {
     
                        wb.Close(0);
                        Marshal.ReleaseComObject(wb);
                        wb = null;
                    }
     
                    if (wks != null)
                    {
                        wks.Close();
                        Marshal.ReleaseComObject(wks);
                        wks = null;
                    }
     
                    if (xlApp != null)
                    {
                        // Close Excel.
                        xlApp.Quit();
                        Marshal.ReleaseComObject(xlApp);
                        xlApp = null;
                    }
     
                    GC.GetTotalMemory(false);
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    GC.Collect();
                    GC.GetTotalMemory(true);
                }
     
                return values;
            }
    La fonction est appellée quatre fois, mais jamais les taches Excel ne sont fermées...
    Je ne sais vraiment plus quoi chercher.

  10. #10
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    Il semblerai que tu ne respecte pas l'ordre donnée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Marshal.ReleaseComObject
    ...
     
    excelWorksheet = null;
    ...
     
    GC.GetTotalMemory(false);
    ...
    Essaye comme ça et fait un test unitaire avec une pause, le process Excel peut mettre quelques secondes a disparaitre.
    (J'ai écrit le code à la volé peut être y aura t'il une erreur de syntaxe)

    Code : 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
    public static object[,] ReadFile(string filepath, string sheetname)
    {
    	Application xlApp = null;
    	Workbooks wks = null;
    	Workbook wb = null;
    	Sheets sheets = null;
    	Worksheet sh = null;
    	object[,] values = null;
    	try
    	{
    		xlApp = new ApplicationClass();
    		wks = xlApp.Workbooks;
    		wb = wks.Open(filepath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);   
    		sheets = wb.Worksheets;
    		sh = (Worksheet)sheets.get_Item(sheetname);
     
    		values = sh.UsedRange.Value2 as object[,];
    	}
    	catch (Exception ex)
    	{
    		throw new Exception(string.Format("Sheet \"{0}\" does not exist in the Excel file", sheetname));
    	}
    	finally
    	{
    		if (wb != null)
    			wb.Close(false, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
     
    		if (wks != null)
    			wks.Close();
     
    		if (xlApp != null)
    			xlApp.Quit();  
     
    		if (sheets != null)
    			Marshal.ReleaseComObject(sheets);
     
    		if (sh != null)
    			Marshal.ReleaseComObject(sh);
     
    		 if (wks != null)
    			Marshal.ReleaseComObject(wks);
     
    		if (wb != null)
    			Marshal.ReleaseComObject(wb);
     
    		if (xlApp != null)
    			Marshal.ReleaseComObject(xlApp);
     
    		sh = null;
    		sheets = null;
    		wks = null;
    		wb = null;
    		xlApp = null;
     
    		GC.GetTotalMemory(false);
    		GC.Collect();
    		GC.WaitForPendingFinalizers();
    		GC.Collect();
    		GC.GetTotalMemory(true);
    	}
     
    	return values;
    }

  11. #11
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2009
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 194
    Points : 102
    Points
    102
    Par défaut
    Hello, merci d'avoir pris le temps de répondre.

    J'ai testé ton code, pas de changement, j'ai toujours mes EXCEL.EXE qui tournent sans jamais se fermer.

    Je précise juste que mes quatre appelles à la fonction "ReadFile()" se font comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     // Read the Excel Sheets
                object[,] toto = ExcelLoader.ReadFile(FilePath1, "sheetname1");
                object[,] tata = ExcelLoader.ReadFile(FilePath2, "sheetname2");
                object[,] titi = ExcelLoader.ReadFile(FilePath3, "sheetname3");
                object[,] tutu= ExcelLoader.ReadFile(FilePath4, "sheetname4");
    Pas sur que ça change grand chose, mais au point où j'en suis...

    J'ai testé tout ce que j'ai trouvé sur le net, notament les préconisations de msdn à savoir passer par Marshal.FinalReleaseComObject() plutôt que Marshal.ReleaseComObject(), pas d'amélioration...

  12. #12
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2009
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 194
    Points : 102
    Points
    102
    Par défaut
    Bon, je ne comprend pas bien.

    Pour tester, j'ai simplifier le code le plus possible.

    Code : 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
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Office.Interop.Excel;
    using System.Runtime.InteropServices;
     
     
    namespace WindowsFormsApplication1
    {
        class Class1
        {
     
            static void Main(string[] args)
            {
                // Display the number of command line arguments:
                object[,] mpart = ReadFile("test.xlsb", "mPart");
                object[,] units = ReadFile("test2.xlsb", "units");
     
            }
     
            private static object missing = System.Reflection.Missing.Value;
            public static object[,] ReadFile(string filepath, string sheetname)
            {
                Application xlApp = null;
                Workbooks wks = null;
                Workbook wb = null;
                Sheets sheets = null;
                Worksheet sh = null;
                object[,] values = null;
                try
                {
                    xlApp = new Application();
                    wks = xlApp.Workbooks;
                    wb = wks.Open(filepath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
                    sheets = wb.Worksheets;
                    sh = (Worksheet)sheets.get_Item(sheetname);
     
     
     
     
     
     
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Sheet \"{0}\" does not exist in the Excel file", sheetname));
                }
                finally
                {
     
     
                    if (wb != null)
                        wb.Close(false, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
     
                    if (wks != null)
                        wks.Close();
     
                    if (xlApp != null)
                        xlApp.Quit();
     
                    if (sheets != null)
                        Marshal.ReleaseComObject(sheets);
     
                    if (sh != null)
                        Marshal.ReleaseComObject(sh);
     
                    if (wks != null)
                        Marshal.ReleaseComObject(wks);
     
                    if (wb != null)
                        Marshal.ReleaseComObject(wb);
     
                    if (xlApp != null)
                        Marshal.ReleaseComObject(xlApp);
     
                    sh = null;
                    sheets = null;
                    wks = null;
                    wb = null;
                    xlApp = null;
     
                    GC.GetTotalMemory(false);
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    GC.Collect();
                    GC.GetTotalMemory(true);
                }
     
                return values;
            }
     
        }
    }
    Ce bout de code rassemble à peu près tout ce que j'ai trouvé sur le net concernant les thread Excel qui ne se ferment pas.
    Et mes threads ne se ferment toujours pas...

    J'ai raté quoi...?

  13. #13
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2009
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 194
    Points : 102
    Points
    102
    Par défaut
    Vraiment personne ? :/

  14. #14
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    Si il ne se ferme toujours pas je ne sais pas.

    On sais qu'Excel as des problème de clôture via les objet COM.
    Il faudrait ré-dévelloper le traitement sans utiliser Excel mais il me semble que c'est une solution banni.

    J'ai cru comprendre qu'il s’agissait d'un projet Entreprise, si ton entreprise à un support chez Microsoft tu peux leur poser la question.

Discussions similaires

  1. [XL-2013] Ajouter un traitement VBA dans un tableau Excel
    Par arnaudperfect dans le forum Excel
    Réponses: 4
    Dernier message: 23/10/2014, 16h06
  2. [AC-2003] Importation d'un fichier excel dans Access avec traitement
    Par Mishe dans le forum VBA Access
    Réponses: 2
    Dernier message: 12/03/2013, 16h23
  3. Réponses: 11
    Dernier message: 04/08/2010, 13h00
  4. Réponses: 2
    Dernier message: 03/06/2005, 10h19
  5. [VB6]PB d'importation d'un feuille Excel dans une MSFlexGrid
    Par mystere l dans le forum VB 6 et antérieur
    Réponses: 18
    Dernier message: 20/04/2004, 15h59

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