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 :

Appel à un Thread à partir d'une fonction Timer


Sujet :

MFC

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Developer
    Inscrit en
    Juin 2004
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Developer

    Informations forums :
    Inscription : Juin 2004
    Messages : 194
    Par défaut Appel à un Thread à partir d'une fonction Timer
    Bonjour,

    Voici un appel a une thread mais a partir d'une fonction OnTImer:

    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
     
    //Dlg_2.cpp
     
     
        / / Global variables
       CDlg_2 * pDlg2; 
     
        UINT MyThreadProc (pParam LPVOID) 
       ( 
     
        pDlg2-> OnButtonBegin (); / / MFC fonction 
     
        return 0; 
       ) 
     
    ....
     
     
    void CDlg_2::OnTimer(UINT nIDEvent) 
    {
     
        if (nIDEvent ==3)  //	
        {	
     
                AfxBeginThread (MyThreadProc, NULL); 
        }
     
     
    ...
     
    }
     
    void CDlg_2::OnButtonBegin() 
    {
    	// TODO: Add your control notification handler code here
     
    	CWaitCursor();
     
    	SHELLEXECUTEINFO sei5;
    	DWORD dw;
     
    	KillTimer(3);
     
    	GetDlgItem(IDC_BUTTON_CAMERA2)->EnableWindow(false);
     
    	if (process_0)
    	{
     
    					process_0 =false;
    					process_1= true;
     
    	}
    	else if (process_1)
    ..
     
    }

    Quand le programme arrive à cette ligne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pDlg2-> OnButtonBegin (); / / MFC fonction
    Puis j'ai debug assertion failed erreur avec CWnd:: KillTimer (nIDEvent int) Pourquoi ?
    Est ce du au fait que j'appel a aprtir d'une fonction TImer ou bien car la fonction thread est une fonction statique et qu'il y a des fonctions MFC dans la fonction OnButtonBegin() est ce la raison ?

    Y a t il est une autre façon d'appeler un thread dans un Timer?

    Merci

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Les MFCs (en particulier ce qui a trait aux fenêtres et au GDI) se marient mal avec le multithread. En général, quand il s'agit d'agir sur l'I.H.M. avec un thread de travail, je préfère envoyer des messages et n'avoir dans le thread de travail aucune interaction directe avec les éléments d'I.H.M.

  3. #3
    Membre confirmé
    Profil pro
    Developer
    Inscrit en
    Juin 2004
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Developer

    Informations forums :
    Inscription : Juin 2004
    Messages : 194
    Par défaut
    Salut,

    Merci donc du multithread avec envoi de messages permettrait aussi d'avoir un control total sur des elements MFC de l' IHM (button, bar progress, etc... ) ?

    C'est quand même dommage vu que la thread est appellé avec un fonction MFC (AfxBeginThread(...) )

    Est si par contre in créait des fonctions thread non static mais propre au projet MFC serait ce possible dans ce cas d'agir sur des controls MFC dans ces fonctions thread?



    Merci

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 502
    Par défaut
    Le "problème" n'est pas dans les MFC, c'est au niveau des objets fenêtre du Kernel que des choix dictées par les performances ont interdit l'accès aux données des fenêtres dans des threads n'ayant pas créés la fenêtre.

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Aliveli Voir le message
    Est si par contre in créait des fonctions thread non static mais propre au projet MFC serait ce possible dans ce cas d'agir sur des controls MFC dans ces fonctions thread?
    A confirmer, mais il me semble que le problème vient de ce que les objets MFC d'I.H.M. (fenêtre, bts de dialogues, ctrl...) sont construit dans l'espace de stockage du thread qui les créé (Thread Local Storage). Qui plus est, ces objets ne sont pas protégés contre des accès concurrent -> situation de compétition potentielle.
    Donc, je continue de penser que dans beaucoup de cas l'envoi de message reste une solution maitrisée et adaptée.

  6. #6
    Membre émérite
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Par défaut
    Salut,
    Les MFCs (en particulier ce qui a trait aux fenêtres et au GDI) se marient mal avec le multithread. En général, quand il s'agit d'agir sur l'I.H.M. avec un thread de travail, je préfère envoyer des messages et n'avoir dans le thread de travail aucune interaction directe avec les éléments d'I.H.M.
    Affirmation fausse

    Si le AfxBeginThread existe dans les MFC elle doit nécessairement servir à quelque chose.

    Dans les MFC nous avons 2 types de thread :
    1. Les threads de travail ( fournir une méthode globale ou statique pour cela)
    2. Les threads d'interface utilisateur (fournir un objet CWinThread pour cela)

    Si un thread veut travailler avec des éléments du GUI le deuxième type de thread est là pour ça.

    Le "problème" n'est pas dans les MFC, c'est au niveau des objets fenêtre du Kernel que des choix dictées par les performances ont interdit l'accès aux données des fenêtres dans des threads n'ayant pas créés la fenêtre.
    +1

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 502
    Par défaut
    cf. ma réponse précédente.
    La limitation n'est pas dans les MFC mais dans le système de fenêtrage du Kernel.
    La différence entre les types de thread MFC est liée aux données TLS utilisées par les MFC pour gérer les fenêtres que le thread crée, il n'y a pas de partage de fenêtre entre les différents threads MFC d'interface utilisateur, c'est juste pour que le thread puisse créer simplement des fenêtres gérables par les MFC.

  8. #8
    Membre émérite
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Par défaut
    Ce que je te reproche c'est ta première réponse brutale qui dit que les MFC se marie mal avec le multithread.

    Pour ce qui est des principes je les connais et je suis tout à fait d'accords avec toi. Chaque thread est responsable des objets qu'il a crée.

    Mais il y a une chose que je veux te dire et je le dis par expérience.

    Un thread de travail peut intéragir avec les éléments de l'HIM du thread principale si le thread travail sait obtenir les handles de ces fenêtres et ainsi poster des messages. Bien sûr ce thread auxiliaires doit tenir compte de la durée de vie de l'IHM et des accès concurrents.

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Gabrielly Voir le message
    Affirmation fausse
    Merci de faire l'effort de lire ce qui a été dit et de se renseigner un peu. Oui on peut utiliser des MFCs dans les threads. Non les objets CWnd and co ne se partagent pas bien. Merci de relire l'entrée de la F.A.Q. Comment travailler sur des objets MFC à partir d'un thread de service ? :
    Citation Envoyé par F.A.Q.
    Donc bien retenir la règle suivante :
    On ne peut pas partager des objets MFC liés aux fenêtres ou d'objets GDI entre plusieurs threads de service.
    On passera le handle de fenêtre en paramètre dans la fonction AfxBeginThread pour établir le lien avec la fenêtre de traitement.
    MSDN :
    For size and performance reasons, MFC objects are not thread-safe at the object level, only at the class level. This means that you can have two separate threads manipulating two different CString objects, but not two threads manipulating the same CString object.
    Et :
    As a general rule, a thread can access only MFC objects that it created. This is because temporary and permanent Windows handle maps are kept in thread local storage to help maintain protection from simultaneous access from multiple threads. For example, a worker thread cannot perform a calculation and then call a document's UpdateAllViews member function to have the windows that contain views on the new data modified. This has no effect at all, because the map from CWnd objects to HWNDs is local to the primary thread. This means that one thread might have a mapping from a Windows handle to a C++ object, but another thread might map that same handle to a different C++ object. Changes made in one thread would not be reflected in the other.

    There are several ways around this problem. The first is to pass individual handles (such as an HWND) rather than C++ objects to the worker thread. The worker thread then adds these objects to its temporary map by calling the appropriate FromHandle member function. You could also add the object to the thread's permanent map by calling Attach, but this should be done only if you are guaranteed that the object will exist longer than the thread.

    Another method is to create new user-defined messages corresponding to the different tasks your worker threads will be performing and post these messages to the application's main window using :ostMessage. This method of communication is similar to two different applications conversing except that both threads are executing in the same address space.
    Sources M.S.D.N. : Multithreading: Programming Tips

Discussions similaires

  1. Argument d'appel de procédure à partir d'une fonction
    Par electrosat03 dans le forum VBA Access
    Réponses: 4
    Dernier message: 30/03/2008, 17h33
  2. Réponses: 4
    Dernier message: 30/11/2007, 14h46
  3. Réponses: 2
    Dernier message: 20/06/2007, 12h12
  4. Appeler une nouvelle fenetre à partir d'une fonction callback
    Par foxyman dans le forum GTK+ avec C & C++
    Réponses: 4
    Dernier message: 02/02/2007, 18h42
  5. Réponses: 1
    Dernier message: 09/08/2006, 16h04

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