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 :

OutOfMemory avec datagridview incompréhensible


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 134
    Par défaut OutOfMemory avec datagridview incompréhensible
    Bonjour à tous, je rencontre un problème avec un datagridview que je n'arrive pas à résoudre seul. J'appelle donc à votre gentillesse et vos connaissance pour m'aider.

    J'ai une list d'object qui comprend +/- 630.000 object.

    j'affiche cette liste dans un datagridview de la manière suivante :

    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
    public void SetMarks(List<Mark> lst)
    		{
    			if (lst.Count == 0 || lst == null) return;
     
    			dtgv.CellFormatting += dtgv_CellFormatting;
     
    			if (dtgv.Rows.Count != 0)
    			{
    				dtgv.DataSource = null;
    				dtgv.Rows.Clear();
    			}
     
    			dtgv.AutoGenerateColumns = false;
    			dtgv.Columns[3].DataPropertyName = "Titre";
    			dtgv.Columns[4].DataPropertyName = "Link";	
    			dtgv.Columns[7].DataPropertyName = "Description";
    			dtgv.Columns[8].DataPropertyName = "KeyWords";
     
    			dtgv.DataSource = lst;
     
    			OnDataChanged();
    		}
     
    		void dtgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    		{
    			int colIndex = e.ColumnIndex;
    			int rowIndex = e.RowIndex;
     
    			Mark mk = dtgv.Rows[rowIndex].DataBoundItem as Mark;
     
    			switch (colIndex)
    			{
    				case 1:
    					dtgv.Rows[rowIndex].Cells[1].Style.BackColor = mk.CheckInfo.Couleur;
    					break;
    				case 2:
    					dtgv.Rows[rowIndex].Cells[2].Value = mk.CheckInfo.CodeRetour;
    					break;
    				case 4:
    					if(Helpers.UrlHlp.IsFromDarkWeb(mk.Link)) dtgv.Rows[rowIndex].Cells[4].Style.ForeColor = Color.Red;
    					break;
    				case 5:
    					if(Helpers.FileHlp.UrlIsFile(mk.Link) == true)
    					{
    						dtgv.Rows[rowIndex].Cells[5].Value = " ";
    						dtgv.Rows[rowIndex].Cells[5].Style.BackColor =	Color.Black;
    					}
    					break;
    				case 6:
    					dtgv.Rows[rowIndex].Cells[6].Value = mk.CheckInfo.RedirectionURL;
    					break;
    			}	
    		}
    jusque là je n'ai pas de problème l'affichage du datagridview ce passe bien.

    Souhaitant supprimer tous les doublons de manière visible, je sélectionne toute les ligne (via un bouton) sauf une avec la procédure suivante:

    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
    	private void BtSelectAllClick(object sender, EventArgs e)
    		{
    			if(dtgv.Rows.Count == 0) return;
     
    			string baseCompare = dtgv.Rows[0].Cells[dtgv.COLLINK].Value.ToString();
     
    			dtgv.SuspendLayout();
    			for(int i = 1; i < dtgv.Rows.Count ; i++)
    			{
    				if(dtgv.Rows[i].Cells[dtgv.COLLINK].Value.ToString() == baseCompare)
    					dtgv.Rows[i].Selected = true;
    				else
    					baseCompare = dtgv.Rows[i].Cells[dtgv.COLLINK].Value.ToString();
    			}
    			dtgv.ResumeLayout();
     
    			dtgv.Focus();
    		}
    et là j'obtiens de manière aléatoire l'erreur suivante :

    à System.Windows.Forms.DataGridViewTextBoxCell.Clone()
    à System.Windows.Forms.DataGridViewRow.CloneCells(DataGridViewRow rowTemplate)
    à System.Windows.Forms.DataGridViewRow.Clone()
    à System.Windows.Forms.DataGridViewRowCollection.get_Item(Int32 index)
    à NoDouble.Gui.Double.SelectAllButOne() dans i:\Perso C#\Webmark-IDEA\WebMark\WebMark\WebMark\Gui\Double.cs:ligne 109
    à NoDouble.Gui.Double.BtSelectAllClick(Object sender, EventArgs e) dans i:\Perso C#\Webmark-IDEA\WebMark\WebMark\WebMark\Gui\Double.cs:ligne 94
    à System.Windows.Forms.Control.OnClick(EventArgs e)
    à System.Windows.Forms.Button.OnClick(EventArgs e)
    à System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
    à System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    à System.Windows.Forms.Control.WndProc(Message& m)
    à System.Windows.Forms.ButtonBase.WndProc(Message& m)
    à System.Windows.Forms.Button.WndProc(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    à System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    la ligne 109 de double.cs est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    				if(dtgv.Rows[i].Cells[dtgv.COLLINK].Value.ToString() == baseCompare)
    					dtgv.Rows[i].Selected = true;
    				else
    					baseCompare = dtgv.Rows[i].Cells[dtgv.COLLINK].Value.ToString();
    La question est donc comment empêcher l'erreur OutOfMemory et comment se fait-il qu'elle se produise puisque l'affichage du datagridview se fait correctement ???

    En tous cas, merci pour votre aide et éclaircissement à venir.

  2. #2
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 941
    Par défaut
    Tu as donné la stacktrace mais pas l'exception qui est levée.

  3. #3
    Membre confirmé
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 134
    Par défaut
    l'exception est System.OutOfMemory

    Ce qui m'étonne c'est que l'erreur survient de manière aléatoire et sans modifier cette partie de code

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 202
    Par défaut
    outofmemory par définition peut arriver n'importe où
    la pile des appels ne sert alors pas à grand chose, car ca peut tomber chez toi comme dans le framework
    elle ne montre que la goutte d'eau qui a fait débordé le vase, pas qui a remplit le vase comme un sagouin sans appeler de Dispose


    par contre ca dit que tu fais un truc qui alloue énormément de mémoire (des centaines de Mo) en très peu de temps
    le garbage collector n'a pas le temps de gérer tout ce qui n'est plus utilisé
    tu peux vérifier dans le gestionnaire de tâches d'ailleurs pour confirmer

    par contre le code que tu nous montre je ne vois rien qui saute aux yeux, tu créés des images ou d'autres trucs volumineux et non managés quelque part ? (ça peut être totalement ailleurs)
    (un logiciel de profiling mémoire .net pourrait te dire quel type d'objet consomme beaucoup de mémoire, et t'aiguiller sur la recherche du code associé, mais c'est pas toujours simple à utiliser)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    La question est donc comment empêcher l'erreur OutOfMemory et comment se fait-il qu'elle se produise puisque l'affichage du datagridview se fait correctement ???
    Ce n'est pas parce que l'affichage se fait sans heurt que tu as suffisamment de mémoire pour gérer toutes les actions. D'ailleurs, il suffit de voir la trace que tu nous as fournis. Avec des méthodes Clone, on peut supposer qu'il y a des copies qui sont effectuées en interne, avec allocation de nouveaux objets donc.

    Pour limiter la consommation mémoire, et vu la taille de la collection, j'utiliserai le mode virtuel du DataGridView. C'est un mode spécial adapté pour les collections très large. L'idée est qu'au lieu d'allouer autant de lignes "graphiques" qu'il y a d'éléments, on utilise un évènement qui permet de retourner les valeurs pour les cellules qui sont affichées. Par contre, cela demande de revoir un peu le code...

  6. #6
    Membre confirmé
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 134
    Par défaut
    Bon ok, merci pour la réponse.

    Le profiling montre bien une utilisation de presque 2Go pour l'application. (et moi qui me croyais à l'abris de ce type de problème avec mes 32 Go).

    J'avais essayé le virtual mode mais j'ai rien compris en ce qui concerne l'affichage des cellule sur le this.dataGridView1.RowCount = 4;. Je suis jamais parvenu à afficher le bon nombre de ligne.

    Bref comme il s'agit d'un petit programme perso, j'ai contourné le problème en faisant l'opération en 4 fois pour travailler sur des liste plus petite...

    Merci pour l'aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [.Net 2.0] Binding avec DatagridView
    Par Mast3rMind dans le forum C#
    Réponses: 2
    Dernier message: 15/11/2007, 20h21
  2. résultat de test avec regex incompréhensible
    Par waldo2188 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 22/09/2007, 17h31
  3. Problème avec DataGridView et Localizable
    Par blistex dans le forum ASP.NET
    Réponses: 3
    Dernier message: 10/07/2007, 16h28
  4. VB.NET Pb de doublons avec Datagridview
    Par Igmar dans le forum Windows Forms
    Réponses: 1
    Dernier message: 02/05/2007, 14h51
  5. [c#] Travail avec datagridview.
    Par penchu dans le forum Windows Forms
    Réponses: 5
    Dernier message: 21/12/2006, 17h59

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