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

Windows Presentation Foundation Discussion :

ObservableCollection ajouter une grosse quantité de données


Sujet :

Windows Presentation Foundation

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur C#
    Inscrit en
    Avril 2011
    Messages
    348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur C#
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 348
    Points : 191
    Points
    191
    Par défaut ObservableCollection ajouter une grosse quantité de données
    Bonjour,

    J'aimerai chargé une ObservableCollection avec plus de 200.000 record.

    Le problème, c'est que ca prend du temps ... :-[


    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
    private ObservableCollection<ConfigMontage> ListAllDossier(String sDenomination)
    {
    	String sqltxt = null;
    	ObservableCollection<ConfigMontage> lstCfMont = null;
    	ConfigMontage cfMont = null;
     
    	MySqlCommand myCmd = null;
    	DataTable table = null;
    	MySqlDataReader dataReader = null;
     
    	try
    	{
    		db.OpenConnection();
     
    		sqltxt = "SELECT * FROM deom.configgrue_viewalldossier WHERE sDenomination = @sDenomination";
    		myCmd = new MySqlCommand(sqltxt, db.Connection);
    		myCmd.Parameters.AddWithValue("@sDenomination", sDenomination);
    		dataReader = myCmd.ExecuteReader();
    		table = new DataTable();
    		table.Load(dataReader);
    		dataReader.Close();
     
    		lstCfMont = new ObservableCollection<ConfigMontage>();
    		foreach (DataRow row in table.Rows)
    		{
    			cfMont = new ConfigMontage()
    				{
    					NIdConfigMon = Convert.ToInt32(row["nIdDossierConfig"]),
    				};
     
    			lstCfMont.Add(cfMont);
    		}
     
    		return lstCfMont;
    	}
    	catch (Exception ex)
    	{ throw ex; }
    	finally
    	{ db.CloseConnection(); }
    Existe-t'il un moyen plus performant que celui ci pour charger des données ?

  2. #2
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 436
    Points : 963
    Points
    963
    Par défaut
    Bonjour, peux tu faire de la pagination ?

    Quelle version du framework .NET utilises-tu ?

    Ainsi tu pourrais utiliser les nouveautés de .NET 4.5 avec async await

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2006
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 243
    Points : 328
    Points
    328
    Par défaut
    Une autre méthode ?

    Pas utilisée avec ce volume de données mais c'est rapide à tester...

  4. #4
    Membre habitué
    Homme Profil pro
    Développeur C#
    Inscrit en
    Avril 2011
    Messages
    348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur C#
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 348
    Points : 191
    Points
    191
    Par défaut
    Bonjour,

    Pagination ?
    C'est à dire charger les données au fur et à mesure ?

    J'utilise le framework 4.0

    Mais je suppose que "async wait" permet de charger quelque chose en mémoire tout en pouvant faire autre chose ?

    Pour ca, y a le backgroundworker qui fonctionne pas trop mal.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 436
    Points : 963
    Points
    963
    Par défaut
    Non, ce que j'avais en tête était du chargement en parallèle (recherche task await async) par exemple envoyer 200 chargement de 1000 lignes.

    Oui pour le chargement au fur et à mesure. Que veux tu faire de ces 200 k lignes ?

  6. #6
    Membre habitué
    Homme Profil pro
    Développeur C#
    Inscrit en
    Avril 2011
    Messages
    348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur C#
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 348
    Points : 191
    Points
    191
    Par défaut
    250Gr,
    J'ai testé cette méthode et je trouve qu'elle n'ajoute rien en terme de performance (je l'ai testée)

    Au final, je dois quand même bourré mes records dans une liste, et c'est la méthode de MyObservableCollection qui va charger les données.

    Pourquoi 200. 000 ?
    J'anticipe le futur :-)
    Cela me permet d'afficher des dossier sauvegardé, et dès que tu dépasse les 5k, ca commence à ramer.
    Mais au final, je dois quand même charger mes 200.000 record dans la mémoire.

    Je vais jeter un oeil sur task await async

  7. #7
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 066
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 066
    Points : 4 233
    Points
    4 233
    Par défaut
    Déjà il faut savoir ce qui est le plus long la requête ou l'insertion des données dans ta list?
    Tu peux utiliser la class StopWatch pour chronométrer le temps mis par chaque étape.
    Pourquoi passes tu par une datatable? Tu peux directement crée un objet ConfigMontage depuis ton reader.
    Tu peux aussi optimiser la requête en ajoutant des index aux bons endroit ou en passant par une procédure stockée (encore que sur une requête aussi simple), tu fais un select * alors que tu n'as besoin que d'un champ.

  8. #8
    Membre habitué
    Homme Profil pro
    Développeur C#
    Inscrit en
    Avril 2011
    Messages
    348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur C#
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 348
    Points : 191
    Points
    191
    Par défaut
    Pourquoi passes tu par une datatable? Tu peux directement crée un objet ConfigMontage depuis ton reader.
    J'ai essayé par le dataReader, et ca me donne a quelque millisecondes prêt de meilleurs performance avec la datatable.

    J'utiliserai quand même la méthode du datareader dorénavant :-)


    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
    select 
            `configgrue_dossierconfig`.`nIdDossierConfig` AS `nIdDossierConfig`,
            `configgrue_grue`.`sNomGrue` AS `sNomGrue`,
            `configgrue_dossierconfig`.`configgrue_Grue_nIdGrue` AS `nIdGrue`,
            `configgrue_dossierconfig`.`Reference` AS `Reference`,
            `configgrue_dossierconfig`.`IsTuning` AS `IsTuning`,
            `configgrue_dossierconfig`.`IsFeuilleCalcul` AS `IsFeuilleCalcul`,
            `configgrue_typemateriel`.`sTypeMateriel` AS `sTypeMateriel`,
            `configgrue_typemateriel`.`sDenomination` AS `sdenomination`,
            `configgrue_dossierconfig`.`entite_client_ID_Clients` AS `entite_client_ID_Clients`,
            `configgrue_dossierconfig`.`entite_client_ID_Clients_Facture` AS `entite_client_ID_Clients_Facture`,
            `configgrue_dossierconfig`.`entite_dealer_IDCon` AS `entite_dealer_IDCon`,
            `configgrue_dossierconfig`.`DateCreation` AS `DateCreation`,
            `configgrue_dossierconfig`.`DateModif` AS `DateModif`,
            `configgrue_dossierconfig`.`Numero` AS `Numero`
        from
            ((`configgrue_dossierconfig`
            left join `configgrue_grue` ON ((`configgrue_dossierconfig`.`configgrue_Grue_nIdGrue` = `configgrue_grue`.`nIdGrue`)))
            left join `configgrue_typemateriel` ON ((`configgrue_typemateriel`.`nIdTypeMateriel` = `configgrue_grue`.`configgrue_TypeMateriel_nIdTypeMateriel`)))
    Ceci est ma requête (une vue stockée dans la DB), je l'ai simplifier ainsi que dans le code au possible.

    L'exécution de la requête pour 12000 record prend 4.5 milliseconndes, c'est le chargement des données dans l'ObservableCollection qui prend une plombe (4.5 seconde).

  9. #9
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 066
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 066
    Points : 4 233
    Points
    4 233
    Par défaut
    Tu as un exemple ici:
    http://dotnet.developpez.com/articles/ado1/csharp/#LVI
    Et si tu passes par une List au lieu d'une observable collection?
    Tu peux mettre le code que tu as actuellement ?

  10. #10
    Membre habitué
    Homme Profil pro
    Développeur C#
    Inscrit en
    Avril 2011
    Messages
    348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur C#
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 348
    Points : 191
    Points
    191
    Par défaut
    même problème

    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
    private ObservableCollection<ConfigMontage> ListAllDossier(String sDenomination)
    {
    	String sqltxt = null;
    	ObservableCollection<ConfigMontage> lstCfMont = null;
    	ConfigMontage cfMont = null;
     
    	MySqlCommand myCmd = null;
    	MySqlDataReader dataReader = null;
     
    	Stopwatch timePerParse;
     
    	try
    	{
    		timePerParse = Stopwatch.StartNew();
     
    		db.OpenConnection();
     
    		sqltxt = "SELECT * FROM deom.configgrue_viewalldossier WHERE sDenomination = @sDenomination";
    		myCmd = new MySqlCommand(sqltxt, db.Connection);
    		myCmd.Parameters.AddWithValue("@sDenomination", sDenomination);
    		dataReader = myCmd.ExecuteReader();
     
    		timePerParse.Stop();
    		MessageBox.Show(timePerParse.Elapsed.TotalMilliseconds.ToString());
     
    		timePerParse = Stopwatch.StartNew();
    		lstCfMont = new ObservableCollection<ConfigMontage>();
     
    		while (dataReader.Read())
    		{
    			cfMont = new ConfigMontage()
    			{
    				NIdConfigMon = Convert.ToInt32(dataReader["nIdDossierConfig"]),
    				SReference = Convert.ToString(dataReader["Reference"]),
    				IsFeuilleCalcul = Convert.ToBoolean(dataReader["IsFeuilleCalcul"]),
    				IsTuning = Convert.ToBoolean(dataReader["IsTuning"]),
    				DateCreation = Convert.ToDateTime(dataReader["DateCreation"]),
    				DateModif = Convert.ToDateTime(dataReader["DateModif"]),
    				SNomGroupe = Convert.ToString(dataReader["sNomGroupe"]),
     
    				App = new Grue()
    				{
    					SReference = Convert.ToString(dataReader["sNomGrue"]),
    					NIdAppareil = Convert.ToInt32(dataReader["nIdGrue"])
    				}
    			};
     
    			lstCfMont.Add(cfMont);
    		}
     
    		MessageBox.Show(timePerParse.Elapsed.TotalMilliseconds.ToString());
     
    		dataReader.Close();
    		return lstCfMont;
    	}
    	catch (Exception ex)
    	{ throw ex; }
    	finally
    	{ db.CloseConnection(); }
    }
    Il faut de toute manière qu'après je transfert ces données dans une observableCollection

  11. #11
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 066
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 066
    Points : 4 233
    Points
    4 233
    Par défaut
    Tu peux aussi te passer des convert en faisant ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                int indexColonneId = reader.GetOrdinal("id");
                if (!reader.IsDBNull(indexColonneId))
                {
                    personne.Id = reader.GetInt32(indexColonneId);
                }
    Je te proposait de passer par une List pour savoir si le problème venait effectivement de l'utilisation d'une ObservableCollection (chez moi je ne vois pas de différence de perf entre les 2 au pire 100ms).


    J'ai testé de mon coté et j'arrive à lire 580 000 lignes et créer une observable collection avec ces données en 1s5.

  12. #12
    Membre habitué
    Homme Profil pro
    Développeur C#
    Inscrit en
    Avril 2011
    Messages
    348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur C#
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 348
    Points : 191
    Points
    191
    Par défaut
    Merci beaucoup pour ton aide, malheureusement, en essayant de cette manière, cela prend exactement le même temps :

    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
    private ObservableCollection<ConfigMontage> ListAllDossier(String sDenomination)
    {
    	String sqltxt = null;
    	ObservableCollection<ConfigMontage> lstCfMont = null;
     
    	ConfigMontage cfMon = null;
    	MySqlCommand myCmd = null;
    	MySqlDataReader dataReader = null;
     
    	Stopwatch timePerParse;
     
    	try
    	{
    		timePerParse = Stopwatch.StartNew();
     
    		db.OpenConnection();
     
    		sqltxt = "SELECT * FROM deom.configgrue_viewalldossier WHERE sDenomination = @sDenomination";
    		myCmd = new MySqlCommand(sqltxt, db.Connection);
    		myCmd.Parameters.AddWithValue("@sDenomination", sDenomination);
    		dataReader = myCmd.ExecuteReader();
     
    		timePerParse.Stop();
    		MessageBox.Show(timePerParse.Elapsed.TotalMilliseconds.ToString());
     
    		timePerParse = Stopwatch.StartNew();
    		lstCfMont = new ObservableCollection<ConfigMontage>();
     
    		int nIdDossierConfig = dataReader.GetOrdinal("nIdDossierConfig");
    		int Reference = dataReader.GetOrdinal("Reference");
    		int IsFeuilleCalcul = dataReader.GetOrdinal("IsFeuilleCalcul");
    		int IsTuning = dataReader.GetOrdinal("IsTuning");
    		int DateCreation = dataReader.GetOrdinal("DateCreation");
    		int DateModif = dataReader.GetOrdinal("DateModif");
    		int sNomGroupe = dataReader.GetOrdinal("sNomGroupe");
    		int sNomGrue = dataReader.GetOrdinal("sNomGrue");
    		int nIdGrue = dataReader.GetOrdinal("nIdGrue");
     
    		while (dataReader.Read())
    		{
     
    			cfMon = new ConfigMontage();
     
    			if (!dataReader.IsDBNull(nIdDossierConfig))
    				cfMon.NIdConfigMon = dataReader.GetInt32(nIdDossierConfig);
    			if (!dataReader.IsDBNull(Reference))
    				cfMon.SReference = dataReader.GetString(Reference);
    			if (!dataReader.IsDBNull(IsFeuilleCalcul))
    				cfMon.IsFeuilleCalcul = dataReader.GetBoolean(IsFeuilleCalcul);
    			if (!dataReader.IsDBNull(IsTuning))
    				cfMon.IsTuning = dataReader.GetBoolean(IsTuning);
    			if (!dataReader.IsDBNull(DateCreation))
    				cfMon.DateCreation = dataReader.GetDateTime(DateCreation);
    			if (!dataReader.IsDBNull(DateModif))
    				cfMon.DateModif = dataReader.GetDateTime(DateModif);
    			if (!dataReader.IsDBNull(sNomGroupe)) 
    				cfMon.SNomGroupe = dataReader.GetString(sNomGroupe);
     
    			cfMon.App = new Grue();
    			if (!dataReader.IsDBNull(Reference))
    				cfMon.App.SReference = dataReader.GetString(Reference);
    			if (!dataReader.IsDBNull(nIdGrue))
    				cfMon.App.NIdAppareil = dataReader.GetInt32(nIdGrue);
     
    			lstCfMont.Add(cfMon);
     
                    }
     
    		MessageBox.Show(timePerParse.Elapsed.TotalMilliseconds.ToString());
     
    		dataReader.Close();
    		return lstCfMont;
    	}
    	catch (Exception ex)
    	{ throw ex; }
    	finally
    	{ db.CloseConnection(); }
    }

  13. #13
    Membre habitué
    Homme Profil pro
    Développeur C#
    Inscrit en
    Avril 2011
    Messages
    348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur C#
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 348
    Points : 191
    Points
    191
    Par défaut
    J'ai trouvé d'ou venait le problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    cfMon.App = new Grue();
    			if (!dataReader.IsDBNull(Reference))
    				cfMon.App.SReference = dataReader.GetString(Reference);
    			if (!dataReader.IsDBNull(nIdGrue))
    				cfMon.App.NIdAppareil = dataReader.GetInt32(nIdGrue);
    Quand j'ajoute une "Grue", j'execute une requête dans le contructeur ....
    Quel erreur de débutant !!

    Merci beaucoup pour votre aide et particulièrement à toi "youtpout978" pour tes est de code ;-)



    Sans l'ajout de Grue, ca roule au poils !

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

Discussions similaires

  1. Réponses: 19
    Dernier message: 06/11/2010, 22h07
  2. Réponses: 11
    Dernier message: 23/09/2008, 15h39
  3. Une grande quantité de données sur Oracle 8i?
    Par bliml dans le forum Oracle
    Réponses: 13
    Dernier message: 01/03/2007, 11h45
  4. Réponses: 1
    Dernier message: 10/01/2007, 15h52
  5. [MySQL] Backup d'une grosse base de données (60MB)
    Par MiJack dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 01/11/2005, 18h22

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