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 :

Probleme de ThreadPool


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut Probleme de ThreadPool
    Bonjour

    J'essaye de lancer un process un peu lourd dans un nouveau thread

    Le premier probleme auquel je me heurte c'est la définition des parametres

    Si j'ai bien lu la doc il existe deux mode d'appel : avec ou sans parametres

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    QueueUserWorkItem(WaitCallback) // Queues a method for execution. The method executes when a thread pool thread becomes available. 
    QueueUserWorkItem(WaitCallback, Object)  // Queues a method for execution, and specifies an object containing data to be used by the method. The method executes when a thread pool thread becomes available.
    Mais si j'essaye sans et donc sans donner de parametre a ma methode appelée je recois un message d'erreur

    Donc actuellement je fais ceci :
    Mais je ne comprends pas comment donner une valeur a 'rien' qui vient de nulle part ?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        private void btnMatrix_Click(object sender, EventArgs e)
        {
          ThreadPool.QueueUserWorkItem(new WaitCallback(Process));
        }
     
        void Process(Object rien)
        {
        }

  2. #2
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Le délégué WaitCallback doit être utilisé avec des méthodes prenant un objet en paramètre et ne renvoyant rien. Même si ta méthode n'a pas besoin de paramètre, tu dois tout de même en mettre un (raison de ton message d'erreur au début donc).

    Ensuite soit tu n'as pas besoin de ce paramètre et tu passes par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ThreadPool.QueueUserWorkItem(new WaitCallback(Process));
    La valeur du paramètre sera alors null.

    Soit tu souhaites utiliser le paramètre et alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ThreadPool.QueueUserWorkItem(new WaitCallback(Process), valeurDuParametre);

  3. #3
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Merci StormimOn

    J'avais fini par digerer le truc (+/-)

    J'ai réussi a faire mon delegate et mon call back
    Mais c'est le genre de truc a faire tout les jours pour s'habituer !

    Car il y a quand meme de quoi se faire un noeud dans les neurones si on n'a pas pris le pli !

    En l'occurence je calcule une matrice asser lourde dont je place le resultat en datatable.
    Pour distraire l'utilisateur, J'update un label a chaque cellule et je met a jour un dgv a chaque row
    Je fais le calcul de la matrice dans un Thread et j'invoke deux delegués pour mes mise a jour !

    pfff : j'ai pris deux nurofen !

  4. #4
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Salut Stormimon

    J'ai une derniere misere que tu va peut-etre m'aider a comprendre
    Je met la source ici pour l'explication

    Je lance le Thread
    J'intercepte deux event
    AddCell et AddRow
    A chaque AddRow je met un DGV a jour dans ma form
    Quand le thread se termine, j'appelle une derniere mise a jour (this.AddRow)

    Mais la j'ai une erreur de conlit de thread ?
    Que dois-je faire pour bien faire ?


    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
    96
    97
    98
    99
    100
    101
    102
    103
    using System;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Windows.Forms;
    using DGVPrinterHelper;
    using System.Threading;
     
     
     
    namespace MapScopeNG
    {
      public partial class frmDist : Form
      {
        DataTable dtAdr = null;
        public frmDist(DataTable dt)
        {
          dtAdr = dt;
          InitializeComponent();
        }
     
        public void ShowMatrix()
        {
          this.Show();
          DistMatrix dm = new DistMatrix();
          dm.AddRow += new DistMatrix.StepRowDelegateHandler(Dist_StepRow);
          dm.AddCell += new DistMatrix.StepCellDelegateHandler(Dist_StepCell);
     
          ThreadPool.QueueUserWorkItem(new WaitCallback(Process),dm);
          int a = 8;
        }
     
        void Process(Object rien)
        {
          DistMatrix dm = (DistMatrix)rien;
          DataTable dtn = dm.getMatrix(dtAdr);
          AddRow(dtn);
          btn_print.Visible = true;
        }
        bool Started = false;
     
     
     
        // *****************************************************************************************
        public delegate void StepCellDelegateHandler(int a, int b);
     
        private void Dist_StepCell(int a, int b)
        {
          if (this.InvokeRequired)
          {
            try
            {
              this.Invoke(new StepCellDelegateHandler(StepCell), new object[] { a, b });
              return;
            }
            catch (Exception)
            {
            }
          }
          this.StepCell(a, b);
        }
        // *****************************************************************************************
     
        private void StepCell(int X,int Y)
        {
          lbl_Progress.Text = string.Format("{0}-{1} / {2}", Y, X,dtAdr.Rows.Count);
        }
     
        // *****************************************************************************************
        public delegate void StepRowDelegateHandler(DataTable dt);
     
        private void Dist_StepRow(DataTable dt)
        {
          if (this.InvokeRequired)
          {
            try
            {
              this.Invoke(new StepRowDelegateHandler(AddRow), new object[] { dt });
              return;
            }
            catch (Exception)
            {
            }
          }
          this.AddRow(dt);
        }
     
        // *****************************************************************************************
        private void AddRow(DataTable Dt)
        {
          dgv_Dist.DataSource = null;
          dgv_Dist.DataSource = Dt;
          foreach (DataGridViewColumn dgvc in dgv_Dist.Columns)
          {
            DataGridViewCellStyle style = new DataGridViewCellStyle();
            style.Format = "N2";
            style.Alignment = DataGridViewContentAlignment.MiddleRight;
            dgvc.DefaultCellStyle = style;
          }
          dgv_Dist.Refresh();
        }
      }
    }

  5. #5
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Tu as juste oublié de mettre un bloc else pour le code à exécuter si InvokeRequired est à true. Résultat, tu exécutes toujours le code même lorsqu'il ne faut pas

    La bonne pratique c'est de rappeler la méthode en cours si InvokeRequired est à true et dans le else mettre le code que doit réaliser la méthode. La méthode est ainsi "illegal-cross-thread-call-safe" si l'on peut dire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private void MaMethode(...)
    {
        if (this.InvokeRequired)
        {
            // On exécute MaMethode sur le thread UI avec la méthode Invoke
        }
        else
        {
            // Code à exécuter
        }
    }

  6. #6
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Salut StormimOn

    Il y a sans doute encore qq chose qui m'échappe
    J'ai adapté suivant ton conseil mais ca ne change rien au probleme

    Pour info :

    1- Le code marchait bien sans cette modif mais mon probleme etait la suite de l'execution APRES le process

    2- La modif que j'ai faite ne change rien a l'execution mais ca plante toujours au meme endroit lorrsque l'on execute btn_print.Visible = true;

    Je comprends pourquoi : on est toujours dans le second Thread

    Ma question maintenant c'est COMMENT signaler la fin de l'execution du thread pour continuer le process normal


    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
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    using System;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Windows.Forms;
    using DGVPrinterHelper;
    using System.Threading;
     
     
     
    namespace MapScopeNG
    {
      public partial class frmDist : Form
      {
        DataTable dtAdr = null;
        bool Started = false;
        public frmDist(DataTable dt)
        {
          dtAdr = dt;
          InitializeComponent();
        }
     
        public void ShowMatrix()
        {
          this.Show();
          DistMatrix dm = new DistMatrix();
          dm.AddRow += new DistMatrix.StepRowDelegateHandler(Dist_StepRow);
          dm.AddCell += new DistMatrix.StepCellDelegateHandler(Dist_StepCell);
     
          ThreadPool.QueueUserWorkItem(new WaitCallback(Process),dm);
        }
     
        void Process(Object rien)
        {
          DistMatrix dm = (DistMatrix)rien;
          DataTable dtn = dm.getMatrix(dtAdr);
          btn_print.Visible = true;
        }
     
        // *****************************************************************************************
        public delegate void StepCellDelegateHandler(int a, int b);
     
        private void Dist_StepCell(int a, int b)
        {
          if (this.InvokeRequired)
          {
            try
            {
              this.Invoke(new StepCellDelegateHandler(StepCell), new object[] { a, b });
              return;
            }
            catch (Exception)
            {
            }
          }
          else
          {
            this.StepCell(a, b);
          }
        }
        // *****************************************************************************************
     
        private void StepCell(int X,int Y)
        {
          lbl_Progress.Text = string.Format("{0}-{1} / {2}", Y, X,dtAdr.Rows.Count);
        }
     
        // *****************************************************************************************
        public delegate void StepRowDelegateHandler(DataTable dt);
     
        private void Dist_StepRow(DataTable dt)
        {
          if (this.InvokeRequired)
          {
            try
            {
              this.Invoke(new StepRowDelegateHandler(AddRow), new object[] { dt });
              return;
            }
            catch (Exception)
            {
            }
          }
          else
          {
            this.AddRow(dt);
          }
        }
     
        // *****************************************************************************************
        private void AddRow(DataTable Dt)
        {
          if (dgv_Dist.DataSource == null)
          {
            dgv_Dist.DataSource = Dt;
            foreach (DataGridViewColumn dgvc in dgv_Dist.Columns)
            {
              DataGridViewCellStyle style = new DataGridViewCellStyle();
              style.Format = "N2";
              style.Alignment = DataGridViewContentAlignment.MiddleRight;
              dgvc.DefaultCellStyle = style;
            }
          }
          dgv_Dist.Refresh();
        }
      }
    }

Discussions similaires

  1. Probleme de rafraichissement d'un BDGrid
    Par marmotte dans le forum Bases de données
    Réponses: 10
    Dernier message: 28/05/2004, 18h07
  2. Réponses: 2
    Dernier message: 30/05/2002, 08h54
  3. Probleme sur les chaines de caractere
    Par scorpiwolf dans le forum C
    Réponses: 8
    Dernier message: 06/05/2002, 19h01
  4. [Kylix] Probleme d'execution de programmes...
    Par yopziggy dans le forum EDI
    Réponses: 19
    Dernier message: 03/05/2002, 14h50
  5. [Kylix] Probleme de nombre flottant!!
    Par yopziggy dans le forum EDI
    Réponses: 5
    Dernier message: 02/05/2002, 10h13

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