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 :

Thread et généricité


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 396
    Par défaut Thread et généricité
    Bonjour,

    je développe actuellement un composant qui permettrait de faire tourner n'importe quelle méthode en background avec plusieurs propriétés.

    Pour se faire, dans mon composant, j'ai un délégué :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public delegate void Delegue<T>(T param);
    et afin d'exécuter une méthode générique passé en paramètre, j'utilise la méthode suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public void whatMustBeRunning<T>(Delegue<T> myMethod, T parameters)
            {
                myMethod(parameters);
            }
    Jusque la aucun problème, je peux facilement exécuter mes méthodes.
    Comme ce-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    composant.whatMustBeRunning(testDelegate, "test");
    Ce que j'aimerais par contre, c'est réussir a exécuter l'instruction ici, dans la méthode DoWork d'un backgroundworker afin que celle-ci soit donc exécuté en arrière plan.

    Etant donnée que j'ai ici un délégué et les paramètres à passer au backgroundworker, j'ai créé une classe intermédiaire :

    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
    public class generiqueMethode<T>
        {
     
            public delegate void Delegue(T param);
            private Delegue<T> monDelegue;
            private T mesParameters;
     
            public generiqueMethode(Delegue<T> myMethod, T parameters)
            {
                monDelegue = myMethod;
                mesParameters = parameters;
                //Thread test = new Thread(myMethod);
     
            }
     
            public void setMethode(Delegue<T> myMethod, T parameters)
            {
                monDelegue = myMethod;
                mesParameters = parameters;
            }
     
            public Delegue<T> getMethode()
            {
                return monDelegue;
            }
     
            public T getParamters()
            {
                return mesParameters;
            }
        }
    En ajoutant la ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    generiqueMethode<T> jeDoisConnuDansLeWorker = new generiqueMethode<T>(myMethod, parameters);
    je peux donc facilement remplir une instance qui retient toutes les informations que je dois passer au backgroundworker.

    Cependant, je ne peux récupérer les informations car pour se faire, je dois déclarer generiqueMethode<T> jeDoisConnuDansLeWorker en global mais a ce moment la, le type T n'est pas reconnu.

    Quelqu'un a une idée ?

    Merci

    A bientôt

  2. #2
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    M'a l'air bien compliqué cette affaire... Quelle est la plus value de ta classe par rapport à un simple backgroundworker ?


    Ta class generiqueMethode<T> ne me semble pas très utile. Si tu as la méthode et le(s) paramètre(s), tu peux créer une méthode anonyme instantanément avec. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    BackGroundWorker bgw = new BackGroundWorker();
    bgv.DoWork += new delegate(object sender, XXXEventArgs e) { myMethod(parameters); }
    bgv.RunWorkerAsync();

  3. #3
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    Moi j'ai l'impression que tu redéveloppes un ThreadPool ... connais tu ?

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 396
    Par défaut
    Pour ce qui est du ThreadPool, je ne connaissais pas, mais ce n'est pas ce que je cherche à faire. Ici je veux pouvoir aider d'autre développeur en leur donnant simplement un composant à instantier et au quel il n'aurait qu'une méthode à appelé et automatiquement cette méthode serait exécuter au second plan avec certains paramètres possibles.

    par contre la solution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    BackGroundWorker bgw = new BackGroundWorker();
    bgv.DoWork += new delegate(object sender, XXXEventArgs e) { myMethod(parameters); };
    bgv.RunWorkerAsync();
    me semble plutôt une bonne idée si ce n'est que le code comme tel ne fonctionne pas, il y a un type expected sur le mot delegate,

    et en essayant d'adapter le tout :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    BackgroundWorker bgw = new BackgroundWorker();
                bgw.DoWork += new System.ComponentModel.DoWorkEventHandler(myMethod);
                bgw.RunWorkerAsync();
    J'obtiens l'erreur suivante :

    Error 1 No overload for 'Delegue' matches delegate 'System.ComponentModel.DoWorkEventHandler' C:\Documents and Settings\nicolas\My Documents\Visual Studio 2008\Projects\Common Component\CDataGridView\ChargeProgressBar.cs 33 27 Custom Compenent
    Et bien entendu, j'ai la même erreur si j'essaye de remplacer le backgroundworker par la création d'une thread.

    Merci de vos réponses

  5. #5
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par zenux Voir le message
    un composant à instantier et au quel il n'aurait qu'une méthode à appelé et automatiquement cette méthode serait exécuter au second plan avec certains paramètres possibles.
    Beh ça s'appelle un BackGroundWorker, ça
    Citation Envoyé par zenux Voir le message
    me semble plutôt une bonne idée si ce n'est que le code comme tel ne fonctionne pas, il y a un type expected sur le mot delegate,
    Comme le XXXMachintruc le laissait supposer, c'était du code approximatif Enlève le mot new (mea culpa), remplace XXXEventArgs par celui qui correspond à l'event DoWork et voilà.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 396
    Par défaut
    Cela ne marche pas non plus. Il n'y a pas de type générique disponible comme action que cela dit.

    J'ai par contre trouvé une solution de remplacement qui fonctionne plutôt bien il me semble.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       timer1.Enabled = true;
                Synchro = myMethod.BeginInvoke(parameters, null, null);
                backgroundWorker1.RunWorkerAsync();
    le timer il me sert pour faire fonctionner une progress bar en boucle pour montrer que le logiciel travail

    le beginInvoke permet de lancer ma méthode générique dans une thread avec les parametres

    et le backgroundworker est une thread qui attend pour arreter la bar de progression.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Synchro.AsyncWaitHandle.WaitOne();  
                timer1.Enabled = false;
    Voilà ca fonctionne plutôt bien mais ca fait quand même 3 thread implicite pour un traitement :s

    Cependant, pour quelqu'un qui ne connait pas les threads, son utilisation est très simple, il insère le composant graphiquement, il choisi si il veut une bar de progression ou non, et ensuite il lui suffit de coder la ligne suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Composant.ExecuteFunction(*methodeAExecuter*, *paramètres*);
    Vous en pensez quoi ?

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

Discussions similaires

  1. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  2. récupérer la valeur de sortie d'un thread
    Par jakouz dans le forum Langage
    Réponses: 3
    Dernier message: 31/07/2002, 11h28
  3. Programmer des threads
    Par haypo dans le forum C
    Réponses: 6
    Dernier message: 02/07/2002, 13h53
  4. Réponses: 5
    Dernier message: 12/06/2002, 15h12
  5. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53

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