Partage
  • Partager sur Facebook
  • Partager sur Twitter

[C#] Application se fige dés qu'on lance action

    13 juin 2019 à 11:56:49

    Bonjour à tous, 

    Je suis débutant en C# et j'ai un souci avec mon programme. 

    Quand je le lance le programme, ma fenêtre apparaît bien mais une fois que je démarre une tache elle se fige. Derrière la tache tourne bien (requête sql + check de fichier xlsx) mais plus rien ne bouge à l'écran.

    J'ai fait des recherches et apparemment c'est souvent lié à des thread ou des background worker pour d'autres. De mon coté je ne sais pas exactement ce que cela implique et si modifier seulement ma class qui effectue les requêtes va arranger la chose. 

    Je vous montre la dite class : 

    using System;
    using System.Windows.Forms;
    using Oracle.ManagedDataAccess.Client;
    
    
    namespace ApplicationDoublon
    {
        public class connexion
        {
            public void CreateMyOracleDataReader(string[,] tab, int nbcol, int nbline, int compteur, string sourcePath, string destinationPath)
            {
                string oradb = "Data Source=(DESCRIPTION="
                                      + "(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=hn)(PORT=1521)))"
                                      + "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=sn)));"
                                      + "User Id=usr; Password=psw;";
                //Chaine de connexion à la base de données
    
                using (OracleConnection conn = new OracleConnection(oradb))
                {
                    conn.Open();
                    {
                        string dosnum;
                        string nabm;
                        int index = 0;
                        int nberror = 0;
                        string[,] finaltab = new string[nbcol + 1, nbline];
                        Console.WriteLine(compteur);
                        for (int i = 0; i < compteur; i++)
                        {
                            try
                            {
                                dosnum = tab[7, i].ToString();
                                nabm = tab[12, i].ToString();
                                //Selectionne le numero d'actes (nabm) et le numero de dossier (dossnum) pour pouvoir requeter dessus 
    
                            }
                            catch
                            {
                                dosnum = " ";
                                nabm = " ";
                                //en cas de cellule vide, remplace les nabm ou dosnum par un espace
    
                            }
    
                            switch (nabm.Length)
                            {
                                case 1:
                                    nabm = "000" + nabm;
                                    break;
    
                                case 2:
                                    nabm = "00" + nabm;
                                    break;
    
                                case 3:
                                    nabm = "0" + nabm;
                                    break;
                                    //normalise le nabm sur 4 caractere (excel supprime les zero et ils sont obligatoires pour requeter)
    
                            }
                            string sql1 = "select count(dosnum) from KALAM01.hvknabm where dosnum = '" + dosnum + "' and nabm = '" + nabm + "'";
                            //compte le nombre de numero d'actes reviennent avec le meme numero de dossier dans la base de données
                            string sql2 = "select typdacc from KALAM01.hrdos where dosnum = '" + dosnum + "'";
                            //récupere le type d'actes de la ligne (pour facilité le tri via excel plus tard)
                            string sql3 = "select CODANO FROM HX01.HNACTEREP WHERE codedest = 'EAI_XML' and codano != 'OK'and DOSNUM = '" + dosnum + "' ";
                            //récupere à chaque passage la derniere ligne du tableau (contient le nombre de fois que reviens un actes sur un numero de dossier)
                            string sql4 = "select ANOM FROM HX01.HNACTEREP WHERE codedest = 'EAI_XML' and codano != 'OK'and DOSNUM = '" + dosnum + "' ";
                            //nouveau tableau qui va acceuillir les informations triées
    
    
                            string count = tab[19, i];
                            string[,] tab2 = new string[nbcol + 1, nbline];
    
                            OracleCommand command = new OracleCommand(sql1, conn);
                            OracleDataReader reader = command.ExecuteReader();
                            //execution de la requete 1
                            while (reader.Read() && index < nbline)
                            {
                                tab2[20, i] = reader.GetValue(0).ToString();
                                for (int j = 0; j < nbcol; j++)
                                {
                                    tab2[j, i] = tab[j, i];
                                }
                                index++;
                                //nouveau tableau combinant le resultat des deux requetes
                            }
    
                            try
                            {
                                if (int.Parse(tab2[19, i]) > int.Parse(tab2[20, i]))
                                {
                                    nberror += 1;
                                    for (int h = 0; h < nbcol + 1; h++)
                                    {
                                        finaltab[h, nberror] = tab2[h, i];
                                    }
                                }
                                //compare le tableau extrait du fichier excel avec la base de données tant que la boucle n'est pas au bout de la BDD
                                //si un actes et un numero de dossier sont présent plus de fois dans le fichier excel que dans la BDD , la ligne est ajoutée au tableau 
                                float avancement = i * 100 / compteur;
                                Console.WriteLine(avancement + "%");
    
                            }
                            catch { }
    
    
                            OracleCommand command2 = new OracleCommand(sql2, conn);
                            OracleDataReader reader2 = command2.ExecuteReader();
                            //execution de la requete 2
                            //rentre le type d'actes dans le NOUVEAU tableau 
                            while (reader2.Read() && index < nbline)
                            {
                                Console.WriteLine(reader2.GetValue(0).ToString());
                                tab2[15, i] = reader2.GetValue(0).ToString();
                            }
    
                            OracleCommand command3 = new OracleCommand(sql3, conn);
                            OracleDataReader reader3 = command3.ExecuteReader();
                            //execution de la requete 3
                            while (reader3.Read() && index < nbline)
                            {
                                Console.WriteLine(reader3.GetValue(0).ToString());
                                tab2[17, i] = reader3.GetValue(0).ToString();
                            }
    
                            OracleCommand command4 = new OracleCommand(sql4, conn);
                            OracleDataReader reader4 = command4.ExecuteReader();
                            //execution de la requete 4
                            while (reader4.Read() && index < nbline)
                            {
                                Console.WriteLine(reader4.GetValue(0).ToString() + "  " + dosnum + " OOO");
                                tab2[18, i] = reader4.GetValue(0).ToString();
                            }
                        }
                        //ferme la connexion à la BDD
                        conn.Close();
                        int colonne = finaltab.GetLength(0); //recupere nombre de colonnes
                        int ligne = finaltab.GetLength(1); // recupere nombre de lignes
    
                        var finalTabInver = new string[ligne, colonne + 2];
                        for (int j = 0; j < nberror; j++)
                        {
                            for (int r = 0; r < nbcol + 1; r++)
                            {
                                finalTabInver[j, r] = finaltab[r, j];
                                if (finalTabInver[20, r] != null)
                                {
                                    try
                                    {
                                        int excelnum = int.Parse(finalTabInver[j, 21]);
                                        int dbnume = int.Parse(finalTabInver[j, 20]);
                                        int difference = excelnum - dbnume;
                                        finalTabInver[j, 22] = difference.ToString();
                                        /* Ce tableau contient toutes les données qui ne sont pas dans la base 
                                        avec la difference entre le nombre d'occurences dans le Excel et celui de la BDD */
                                    }
                                    catch { }
                                }
                            }
                        }
                        writeExcel WriteExcel = new writeExcel();
                        WriteExcel.CreateExcel(finalTabInver, ligne, sourcePath, destinationPath);
                        //instanciation de la table writeExcel
                       
                    }
                }
            }
        }
    }

    -
    Edité par Sin77 13 juin 2019 à 11:58:27

    • Partager sur Facebook
    • Partager sur Twitter
      17 juin 2019 à 9:46:35

      Bonjour Sin77,

      Sur une application lorsque tu lance une tâche par défaut elle utilise le Thread de ton application. Donc tant que ta tâche est exécuté ton application elle ne répond pas.

      Je te conseil donc d'ouvrir un BackgroundWorker pour toutes les longues tâches de ton application.

      • Partager sur Facebook
      • Partager sur Twitter

      Cordialement,

      Neross

      Vous pouvez m'ajouter sur Discord : Neross#8583

        17 juin 2019 à 12:26:22

        Bon, votre code utilise cette putain d'antiquité qu'est un DataReader, laissez tomber cette cochonnerie pour de simples DataAdapter/DataSet.

        N'utiliser pas de requête SQL "dynamique" mais des requêtes paramétrées, bien plus sûr et bien plus maintenable.

        Utilisez une seule requête qui utilise intelligemment les jointures externes SQL que cette cascade de requêtes des plus lourdes, inélégantes et surtout sources d'erreurs à répétition.

        De la ligne 12 à la ligne 139, une seule requête paramétrée avec jointure externe dans un DataSet via un DataAdapter ne prendrait que quelques lignes très très simples.

        L'utilisation des fonctionnalités de "grouping" des DataSet/DataTable/DataView/LINQ permettrait de simplifier les mécanismes de générations des données.

        Votre problème initial est un problème qui se produit quand votre méthode prend "trop" de temps.

        Le multi-threading est souvent une bonne solution mais cela implique une bien plus grande complexité, donc, on l'évite au maximum quand on le peut.

        Si vous gagnez en performance, comme avec mes précédents conseils, vous n'aurez vraisemblablement plus besoin de passer par le multi-threading. Et même si cela ne suffit pas, un code plus simple est bien plus facile à rendre "multi-thread" aware qu'un code complexe avec des requêtes "à tiroirs".

        Vous utilisez "using" et c'est très bien mais il reste pas mal d'erreur de débutant.

        Votre chaine de connexion, ne la mettez pas dans votre code mais dans votre fichier de configuration, c'est plus simple à gérer et c'est bien plus "sécurisable" que dans le code.

        Pas la peine "d'Open" la connexion, c'est totomatique et il faut laisser le framework optimiser le bidule.

        Pas de try/catch{}, on ne catche que ce que l'on sait gérer, donc le type de l'exception EST OBLIGATOIRE (et pas Exception, SVP).

        Bon avec DataSet, on se débarrasse de tous ces tableaux et boucles foireuses.

        • Partager sur Facebook
        • Partager sur Twitter
        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
          18 juin 2019 à 9:19:17

          Je vais tenter d'appliquer toutes vos améliorations 

          Merci beaucoup 

          • Partager sur Facebook
          • Partager sur Twitter

          [C#] Application se fige dés qu'on lance action

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown