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

MFC Discussion :

[MFC] Problème de Threads + Timers


Sujet :

MFC

  1. #1
    Invité
    Invité(e)
    Par défaut [MFC] Problème de Threads + Timers
    Bonjour,
    Après de longues recherches sur le forum, je n'ai pas trouvé de cas similaire donc je ne pense pas vraiment que mon problème est récurrent.

    Idée principale: Je souhaite lancer une application serveur et plusieurs applications clients, les applications clients se connectant au serveur via send() et recv() avec un système de thread que je possède déjà.
    Il y a donc un thread listen sur le serveur qui crée automatiquement un thread supplémentaire pour chaque client avec un recv(). La fermeture client est contrôlée, la fermeture du serveur ferme tous les clients via un système de paquets avec lecture d'entête. Pour le fonctionnement serveur / clients, tout fonctionne. Je pars donc d'un programme qui roule.

    C'est la que ca se complique. Je suis parti d'un mode console pour passer au mode graphique. J'utilise les MFC car j'ai Visual.NET.

    J'ai commencé un projet MFC, de type boite de dialogue pour mon serveur. J'ai fait mon interface en insérant des composants sur ma boite, et placé un (CMyDialog:UpdateData() après avoir modifié mes variables d'initialisation et de début de programme.
    Mais voilà, je souhaite avoir la mise à jour de ces variables dès lors que les clients arrivent sur le serveur. Comme je ne peux pas mettre d'UpdateData() dans mes threads car ils seraient isolés de la classe de la boite de dialogue (j'ai essayé, ca n'a pas marché mais j'ai vu que les attributs de la boite de dialogue étaient exportables). J'ai tenté de mettre un timer avec la fonction (CMyDialog:OnTimer() dans mon thread. Rien y fait.
    Je voudrais donc savoir s'il y a une solution élégante pour mettre à jour les éléments de la boîte de dialogue.
    J'ai réfléchi que le DoModal() peut être la cause de ce problème. Mais je n'ai pas d'idée pour pouvoir gérer efficacement le problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    // Ici il y avait du code mais il était périmé. Il a été retiré car il nuisait à la compréhension générale.
    En rajoutant un Timer, ca ne marche pas (je placais le SetTimer() et le OnTimer() dans cette méthode, et un KillTimer dans le OnOk() + OnCancel().
    J'ai essayé de mettre le OnTimer dans un thread grâce à un pointeur sur la classe CDialog, ca ne marche pas non plus.

    J'attends donc vos suggestions. Merci d'avance.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bon, j'avance car j'ai trouvé d'autres documents sur la question. S'il y a une solution rapide avant que je trouve par moi même je suis toujours preneur.
    Merci.

  3. #3
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    voir faq:
    http://c.developpez.com/faq/vc/?page...d#WorkerThread
    http://c.developpez.com/faq/vc/?page...PrivateMessage
    la solution consiste a envoyer un message privé a la fenetre depuis le thread de service .
    c'est dans ce message que l'on mettra a jour l'interface..

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bon, je vais étudier ça sérieusement. C'est la FAQ qui est venue à moi, je l'avais parcourue mais apparement pas assez pour découvrir cette section.
    Donc merci Farscape, je sens que je vais devenir un pro des multithreads.

  5. #5
    Invité
    Invité(e)
    Par défaut
    J'ai repris du code de la FAQ, mais je suis confronté à quelques problèmes qui peuvent être critiques.

    La libération de la mémoire ne s'effectue pas correctement. Pourtant, j'utilise le code conseillé de "Comment arrêter un thread de travail ?".

    J'ai aussi des questions à propos de ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // depart du thread
    AfxBeginThread(ThreadFunction, this);
    1) Pourquoi ne récupère-t'on pas le HANDLE ?
    2) Dois-je créer un CWorkerThread dynamique avec un new / delete ou un objet statique ?
    3) où placer les initialisations ? Dans la boite de dialogue dans InitInstance ou dans l'application App ?

    Merci d'avance.

  6. #6
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    Citation Envoyé par rockthat
    J'ai repris du code de la FAQ, mais je suis confronté à quelques problèmes qui peuvent être critiques.

    La libération de la mémoire ne s'effectue pas correctement. Pourtant, j'utilise le code conseillé de "Comment arrêter un thread de travail ?".
    où sont declarées ses variables ?
    Citation Envoyé par rockthat
    J'ai aussi des questions à propos de ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // depart du thread
    AfxBeginThread(ThreadFunction, this);
    1) Pourquoi ne récupère-t'on pas le HANDLE ?
    le handle est utile si tu a l'intention de suspendre le thread par exemple.
    ou en dernier recours apres les autres tentatives normales sa destruction brutale ..

    Citation Envoyé par rockthat
    2) Dois-je créer un CWorkerThread dynamique avec un new / delete ou un objet statique ?
    la gestion de ton thread peut se faire directement dans ta classe fenêtre
    donc toute les fonctions de la faq "CWorkerThread" peuvent etre incluses directement dans ta classe fenêtre ,comme ça pas de question a se poser .
    c'est un choix d'architecture à faire : tu as besoin d'un objet separé pour gerer le thread ?
    oui :,arlors qu'il soit dynamique ou statique ce n'est pas un probleme.
    Non:alors inclus la gestion de thread dans ta classe fenêtre.

    Citation Envoyé par rockthat
    3) où placer les initialisations ? Dans la boite de dialogue dans InitInstance ou dans l'application App ?
    les initialisations graphiques doivent etre faites dans la boîte de dialogue .
    le reste ou c'est le plus approprié.

  7. #7
    Invité
    Invité(e)
    Par défaut
    C'est génial Farscape, j'ai trouvé avant que tu me répondes. Cependant, ma façon de coder a été très différente de celle de la FAQ.

    J'ai quand même repris les bonnes idées : L'envoi de messages par la fonction MFC PostMessage() qui me permet de faire un UpdateData() dans OnReceive() dès une manifestation de la part du thread.

    Ma fonction threadée est un TimerUpdate() qui reprend en parametre un LPVOID pParam, la boite de dialogue. L'ouverture et la fermeture du thread sont contrôlées par la boite de dialogue mais la condition d'arrêt pour l'ouverture et la fermeture est une structure indépendante.
    Cela me permet de n'avoir aucune fuite de mémoire, en outre j'utilise ::WaitForSingleObject() à la fermeture.

    Voici le code pour ceux qui sont intéressés:
    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
     
    //srv est une classe indépendante de CMyDlg
     
    ***************** fichier .h *****************
    #define WM_TEST WM_USER+100
     
    class CMyDlg
    {
    	//[..]
    public:
    	// fonction de réponse pour le message privé
    	long OnReceiveTest(WPARAM wparam,LPARAM lparam);
    };
     
    ***************** fichier .cpp *****************
     
    BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
    	//[..]
    	ON_MESSAGE(WM_TEST, OnReceiveTest)  // message privé
    END_MESSAGE_MAP()
     
    UINT CMyDlg::TimerUpdate(LPVOID pParam)
    {
    	CMyDlg* pDlg = reinterpret_cast<CMyDlg *>(pParam);
     
    	while (srv.GetTimer() != 0)
    	{
    		::PostMessage((HWND)pParam, WM_TEST, 0, 0);
    		Sleep(1000);
    	}
    	return 0 ;
    }
     
    void CMyDlg::CloseThread()
    {
    	if (_thread)
    	{
    		// place le timer de contrôle à 0
    		srv.SetTimer(0);
    		Sleep(1001);
    		// attend que le thread soit terminé
    		::WaitForSingleObject(_thread, INFINITE);
    	}
    }
     
    long CMyDlg::OnReceiveTest(WPARAM wparam, LPARAM lparam)
    {
    	//Mon code de contrôle MFC
    	//[..]
    	UpdateData(false);
    	return 0L;
    }
     
    BOOL CMyDlg::OnInitDialog()
    {
    	//[..]
    	_thread = AfxBeginThread(TimerUpdate, GetSafeHwnd(), THREAD_PRIORITY_NORMAL);
    	if (_thread == NULL)
    		AfxMessageBox("L'horloge ne s'est pas déclenchée", MB_ICONINFORMATION);
    }
    Si ca se trouve, ce n'est pas parfait mais moi, du moment que ca marche et qu'il y a pas de fuites mémoires, ca me suffit amplement !
    Merci pour tout Farscape, modifie ta FAQ en tout cas pour que ce soit plus clair

  8. #8
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    si c'est ok pense a mettre resolu sur ton post avec le bouton en bas a gauche.

  9. #9
    Invité
    Invité(e)
    Par défaut
    C'est fait.
    Merci encore pour ton aide précieuse.

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

Discussions similaires

  1. Problème "Exception in thread "Timer-0""
    Par marouene_ dans le forum Général Java
    Réponses: 8
    Dernier message: 16/12/2011, 15h04
  2. Problème avec un Timer/Thread
    Par Mede12 dans le forum Général Java
    Réponses: 4
    Dernier message: 30/07/2009, 09h23
  3. Réponses: 7
    Dernier message: 18/09/2006, 22h01
  4. [VC++ - MFC] Problème de Timer
    Par Alice9 dans le forum MFC
    Réponses: 4
    Dernier message: 08/02/2006, 13h51
  5. Réponses: 5
    Dernier message: 10/05/2005, 10h22

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