Threader simplement une classe pour interagir avec une form

Soyez le premier à donner votre avis sur cette source.

Vue 11 879 fois - Téléchargée 669 fois

Description

Il s'agit d'une classe dont la procédure principale fonctionne sur un Thread différent si une Form a été indiquée dans le constructeur (ici, la procédure ne fait rien à par se reposer...lol). Le pricincipe de cette classe est d'avoir un évenement permettant de communiquer entre le Thread et la Form... je sais qu'il en doit exister pas mal sur le principe de L'Invoke des "Controles", mais j'ai perso cherché un moment avant de trouver un truc simple. Je trouve donc que cette manière de procéder est très simple, et encore plus lors de l'utilisation de la classe (voir le zip).
Ici, le délégué passe en paramètre des informations de progression, mais on peux imaginer passer n'importe quels autres données.

Source / Exemple :


using System;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ThreadWinForm
{
    /// <summary>
    /// Modèle pour les transmitions de messages entre un Thread et une Form
    /// </summary>
    /// <param name="Value">Pourcentage d'avancement du Thread</param>
    /// <param name="Message">Message correspondant à l'avancement</param>
    public delegate void OnProgressHandler(int Value, string Message);
    /// <summary>
    /// Classe dont l'action principale fonctionne sur un Thread
    /// </summary>
    public class ThreadProgress
    {
        /// <summary>
        /// Constructeur sans Form
        /// </summary>
        public ThreadProgress() { }
        /// <summary>
        /// Constructeur avec Form
        /// </summary>
        /// <param name="FormStartThread">Form sur laquelle interagir</param>
        public ThreadProgress(Form FormStartThread)
        {
            _formStartThread = FormStartThread;
        }

        private Thread myThread;
        /// <summary>
        /// Evenement de progression du Thread
        /// </summary>
        public event OnProgressHandler OnProgress;
        private Form _formStartThread;
        /// <summary>
        /// Form sur laquelle interagir
        /// </summary>
        public Form FormStartThread
        {
            get { return _formStartThread; }
            set { _formStartThread = value; }
        }

        /// <summary>
        /// Procédure de lancement du Thread
        /// </summary>
        public void Start()
        {
            if (OnProgress != null && _formStartThread != null)
                myThread = new Thread(new ThreadStart(ActionThreadMessForm));
            else
                myThread = new Thread(new ThreadStart(ActionThreadNoMess));
            myThread.Start();
        }

        /// <summary>
        /// Lancement du Thread avec traitement du délégué
        /// </summary>
        private void ActionThreadMessForm()
        {
            for (int i = 1; i <= 100; i++)
            {
                Thread.Sleep(100);
                try
                {
                    _formStartThread.Invoke(OnProgress, i, string.Format("Vous êtes à {0}%", i));
                }
                catch
                {
                    myThread.Abort();
                }
            }
        }

        /// <summary>
        /// Lancement du Thread seul
        /// </summary>
        private void ActionThreadNoMess()
        {
            for (int i = 1; i <= 100; i++)
            {
                Thread.Sleep(100);
            }
        }
    }
}

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
219
Date d'inscription
jeudi 6 juillet 2006
Statut
Membre
Dernière intervention
7 septembre 2009

C'était juste un exemple d'implémentation et d'utilisation de Control.Invoke()
Messages postés
8
Date d'inscription
jeudi 26 juillet 2007
Statut
Membre
Dernière intervention
11 mai 2010

Pardon, l'avant dernière ligne doit être : refThreadProgress.OnProgress(i);
Messages postés
8
Date d'inscription
jeudi 26 juillet 2007
Statut
Membre
Dernière intervention
11 mai 2010

Tu peux encore 'simplifier' ta classe ThreadProgress ,en tout cas la rendre plus générale. Elle doit être 'intermédiaire' entre le traitement -ici téléchargement par exemple- et l'écouteur -ici la form et l'affichage de progression. Donc tu peux :
- 1 : Brancher des méthodes ('en écoute') à ton 'OnProgressHandler' (qu'on pourrait appeler evenOnProgress) qui se chargeront de l'affichage (et autres). 2 : Le traitement peut être extérieur à ta classe (avec bien sûr une 'réf' sur la méthode d'appel 'On...()', public et lançant l'évènement).
D'où 'séparation' de l'affichage avec le traitement (ActionThreadMessForm).
- Le 'invoke' peut alors être placé dans ta méthode 'évènement' cad OnProgress.
-cad : Classe traitement --appel--> classe intermédiaire, évènement 'On...' --propage (avant de rendre la main) l'appel--> sur le thread de la form avec la ou les méthode(s) (ou rien.. si _formStartThread à null) en écoute.
- Modif :
public event OnProgressHandler evenOnProgress;//au lieu de OnProgress. public pour ajout 'écouteur(s)'
public void OnProgress(int i){
if (_formStartThread != null && _formStartThread.InvokeRequired)
_formStartThread.Invoke(evenOnProgress, new object[] {i});
else
evenOnProgress(i);}

///////Et dans la classe de traitement :
private ThreadProgress refThreadProgress;
public void Start(){
//traitement....
refThreadProgress.Progress(i);
//suite du traitement...

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.