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] question concernant le comportement de CWnd::OnTimer()


Sujet :

MFC

  1. #1
    r0d
    r0d est actuellement connecté
    Expert éminent

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 266
    Points : 6 688
    Points
    6 688
    Billets dans le blog
    2
    Par défaut [MFC] question concernant le comportement de CWnd::OnTimer()
    Bonjour à tous,

    Le timer de la classe CWnd est très pratique. Malheureusement pas très précis, mais d'une facilité d'utilisation vraiment agréable. Mais son comportement n'est pas précisé dans la msdn, et notamment que ce passe-t-il dans le cas ci-dessous:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void MaDlg::OnTimer(UINT nIDEvent)
    {
    	switch (nIDEvent)
    	{
    	case 1:
    		maFonction();
    	break;
     
    	...
    	}
    }
    Dans ce cas, on a une fonction appelée à chaque fois que OnTimer est appelé. La fréquence à laquelle est appelée OnTimer() dépend des paramètres de SetTimer().

    Question: que se passe-t-il si maFonction() n'a pas fini d'être exécutée quand OnTimer() est apellé à nouveau?

    merci.

  2. #2
    Membre actif Avatar de lenouvo
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 252
    Points : 203
    Points
    203
    Par défaut
    et bien soit le programme instancie ta fonction une 2eme fois, soit ca plante.

  3. #3
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Points : 138
    Points
    138
    Par défaut
    Salut,
    Ta fonction sera appelée deux fois par le même thread, ce qui peut être dangereux.
    On peut avoir le même problème lors d'un clique sur un bouton, deux cliques appelant une fonction qui rend la main mais qui n'a pas terminée sont traitement lors du deuxième clique.

  4. #4
    r0d
    r0d est actuellement connecté
    Expert éminent

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 266
    Points : 6 688
    Points
    6 688
    Billets dans le blog
    2
    Par défaut
    En fait, je viens de faire le test suivant:
    Je lance simultanément 2 timers, tous les 2 avec un timeout de 500 ms chacun.
    A l'appel de OnTimer, chacun écrit, dans une list box (mclbMain), le temps écoulé depuis le début.

    Voici le code:
    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
    BOOL CTestTimerDlg::OnInitDialog()
    {
    ...
    	muiTimer1 = (UINT) SetTimer(0, 500, NULL); 
    	muiTimer2 = (UINT) SetTimer(1, 500, NULL);
    	mbTimeSet = FALSE;
    ...
    }
     
    void CTestTimerDlg::OnTimer(UINT nIDEvent)
    {
    	DWORD dwNewTime;
    	CString csTemp, csTemp2;
     
    	if (!mbTimeSet)
    	{
    		mdwInitTime = GetTickCount();
    		mbTimeSet = TRUE;
    	}
    	dwNewTime = GetTickCount();
    	csTemp.Format("%d",(int) dwNewTime-mdwInitTime);
     
    	switch (nIDEvent)
    	{
    	case 0:
    		csTemp2.Format("%s%s","Timer 1 :  ",csTemp);
    		mclbMain.AddString(csTemp2);
    		fnWait();
    		break;
     
    	case 1:
    		csTemp2.Format("%s%s","Timer 2 :  ",csTemp);
    		mclbMain.AddString(csTemp2);
    		break;
    	}
     
    	CDialog::OnTimer(nIDEvent);
    }
     
    void CTestTimerDlg::fnWait()
    {
    	mclbMain.AddString("wait 1");
    	Sleep(1000);
    	mclbMain.AddString("wait 2");
    }
    Et le résultat:
    Citation Envoyé par mclbMain
    timer2 : 0
    timer 1: 0
    wait 1
    wait 2
    Timer 2 : 1000
    Timer 1 : 1000
    wait 1
    wait 2
    Timer 2 : 2000
    Timer 1 : 2000
    etc...
    Ce qui prouve que:

    Un seul thread gère tout ça, même s'il y a plusieurs timers. Le Timer2 aurait dû être exécuté toute les 500 ms, or on voit ici qu'il attend que le Timer1 ait terminé son travail. Idem pour Timer1, il attend que lui-même ait fini son job avant de continuer.

    Maintenant, je n'ai pas l'impression que ce soit dangereux (alors que l'exemple de 2 clics sur un bouton peut l'être, c'est pour cette raison que j'"encadre" mes fonction OnBnClickMachin avec des locks (de simples booleens) ). En effet:

    Citation Envoyé par msdn
    A time-out value is specified, and every time a time-out occurs, the system posts a WM_TIMER message to the installing application's message queue
    Ce qui signifie (je crois) que le timer fonctionne ainsi:
    1/ Il lance le message WM_TIMER
    2/ Le message est traité.
    3/ x millisecondes (time_out) après, WM_TIMER est lancé (mis dans la file des messages)
    4/ quand le message peut-être traité, il l'est.
    5/ retour au 3/

    Donc en fait, pas de risque d'overflow ou de choses dans ce goût. Enfin si j'ai bien compris.

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

Discussions similaires

  1. [MFC] question sur CWnd::GetWindowRect
    Par r0d dans le forum MFC
    Réponses: 2
    Dernier message: 12/05/2006, 11h07
  2. question sur le comportement des threads
    Par rose-bonbon dans le forum CORBA
    Réponses: 4
    Dernier message: 27/10/2004, 19h00
  3. Réponses: 7
    Dernier message: 10/09/2004, 15h28
  4. [Indy] Questions concernant l'envoi de mail
    Par delphicrous dans le forum Web & réseau
    Réponses: 3
    Dernier message: 24/06/2004, 16h06
  5. Question concernant l'API "WaitforSingleObject
    Par Drooxy dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 29/03/2003, 08h26

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