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 :

Multithreader un "démon"


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Par défaut Multithreader un "démon"
    Bonjour,

    j'ai une classe "démon", qui réalise un traitement et je veux attendre que celui-ci se termine avant de passer à la suite car je souhaite récupérer son résultat...

    Le problème c'est que lorsque je réalise se traitement, mon application reste figée également et je ne peux rien faire en parallèle.

    Ma question étant donc, comment je peux attendre la fin du traitement tout en ayant la possibilité de pouvoir naviguer dans mon application?

    Admettons le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    gps = new GpsDecoder.GpsDecoder();
    gps.Open();
     
    pos = gps.GetValidPosition((int)new TimeSpan(0, 5, 0).TotalMilliseconds);
    Fonction bête et méchante :
    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
            public ValidGpsPosition GetValidPosition (int timeout)
            {
                int it = 0;
                while ((!position.IsValid) && it < timeout)
                {
                    Thread.Sleep(1000);
                    it += 1000;
                }
     
                if(it >= timeout)
                {
                    throw new TimeoutException("Timeout levé");
                }
     
                return position;
            }
    Une idée de comment Threader la chose tout en ayant le contrôle et que l'ordre d'éxecution soit respecté?

    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

  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
    La solution classique dans ce cas de figure c'est de faire le début du programme, de lancer le traitement "lourd" dans un autre thread (pour ne pas bloquer le reste de l'application) et de poursuivre le reste du programme une fois le traitement terminé.

    Dans ton cas, tu pourrais le faire avec un appel de méthode asynchrone. La méthode sera exécutée dans un autre thread, évitant ainsi de bloquer le thread principal

    Cela ressemblerait à quelque chose comme ceci
    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
    public class GpsDecoder
    {
        private delegate ValidGpsPosition GetValidPositionDelegate(int timeout);
     
        public ValidGpsPosition GetValidPosition(int timeout)
        {
            ...
        }
     
        public IAsyncResult BeginGetValidPosition(int timeout, AsyncCallback callback)
        {
            GetValidPositionDelegate dlg = GetValidPosition;
     
            return dlg.BeginInvoke(timeout, callback, dlg);
        }
     
        public ValidGpsPosition EndGetValidPosition(IAsyncResult asyncResult)
        {
            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }
     
            GetValidPositionDelegate dlg = asyncResult.AsyncState as GetValidPositionDelegate;
            if (dlg == null)
            {
                throw new NullReferenceException("dlg");
            }
     
            return dlg.EndInvoke(asyncResult);
        }
    }
    A l'utilisation
    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
    GpsDecoder g = new GpsDecoder();
     
    private void DebutProgramme()
    {
        ...
        // Appel du traitement en asychrone.
        g.BeginGetValidPosition(1000, Callback);
    }
     
    private void Callback(IAsyncResult result)
    {
        // Appel asynchrone terminé, on reprend la main
        ValidGpsPosition position = g.EndGetValidPosition(result);
        // Reste du programme
        ...
    }

  3. #3
    Membre éprouvé

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Août 2008
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Août 2008
    Messages : 76
    Par défaut
    Salut,

    Je crois que tu peux arriver au résultat recherché en utilisant la classe System.ComponentModel.BackgroundWorker

    Cette classe propose un événement RunWorkerCompleted qui est déclenché quand le travail est fini. Ca donnerait un code comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += "Ici la methode qui fait le travail"
    bw.RunWorkkerCompleted += "Ici methode a appeler quand le travail est finit"
     
    //lancer le traitement
    bw.RunWorkerAsync();
    Les 2 methodes doivent respecter une signature spécifique (regarde la doc, je n'ai pas les signatures en tête).

    Voici un tuto sur le site qui parle de cette classe http://glarde.developpez.com/dotnet/bgworker/

    En espérant que celà répond à ton besoin.

  4. #4
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Par défaut
    Merci pour vos réponses.

    StormimOn > j'ai retenu ta solution, merci
    phertzog > j'utilise le Compact Framework et donc, pas de BackgroundWorker...
    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

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

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