Page 1 sur 1

Comment arreter proprement une thread ?

Publié : mar. 26/juil./2005 11:47
par olivier
Voila dans mon lecteur d'image, je fais calculer les vignettes des photos et je les affiches au fur et à mesure....
Lorsque l'utilisateur clique sur un autre répertoire je doit arreter la thread qui calcule les photos pour la relancer pour un nouveau répertoire.

Je donne ici un exemple simplifier du problème.
Lorsque l'on clique sur compteur, le compteur défile correctement.
Lorsque l'on clique sur stop, la variable fin_thread se met à 1 et arrete le compteur ! Mais la thread ne va pas au bout de son code pour donner la confirmation de l'arret (fin_thread=2). Comme si la thread était arrete par le Delay ???

Voila si quelqu'un pouvais m'aider, merci d'avance :wink:

Code : Tout sélectionner

Global fin_thread

Procedure creer_vignette_thread(ess)
    i=1
    Repeat 
        i=i+1
        Delay(100)
        SetGadgetText(4,Str(i))
      
    Until i=10000 Or fin_thread=1
        
    fin_thread=2
EndProcedure

If OpenWindow(0,10,10, 150, 300, #PB_Window_SystemMenu ,"memory")
  If CreateGadgetList(WindowID(0))
    ButtonGadget(1, 50, 75, 100, 20, "compteur" ,#PB_Button_Default)
    ButtonGadget(2, 50, 120, 100, 20, "stop compteur" ,#PB_Button_Default)
  EndIf


Repeat 
  EventID.l = WaitWindowEvent()

  If EventID = #PB_EventGadget
    Select EventGadgetID()
        Case 1
            OpenWindow(3,200,100, 300, 200, #PB_Window_SystemMenu ,"ess")
            If CreateGadgetList(WindowID())
                
                TextGadget(4, 10, 10,250,20,"compteur") 
                
            EndIf
            CreateThread(@creer_vignette_thread(),ess)
        Case 2
            fin_thread=1
            Repeat
                Delay(5)
            Until fin_thread=2
            MessageRequester("alerte","fin thread",0)
    EndSelect
  EndIf

  If EventID = #PB_EventCloseWindow
    If EventWindowID() = 0
        Final.l = 1
        CloseWindow(0)
        CloseWindow(3)
    Else
        CloseWindow(3)
    EndIf
    
    
  EndIf
Until Final.l = 1 

EndIf
End

Publié : mar. 26/juil./2005 12:11
par gansta93
Bonjour,

Pourquoi n'utilise-tu pas KillThread ?

Publié : mar. 26/juil./2005 12:36
par olivier
La thread ouvre des images, les retailles, les affiches...
Avec un killthread, j'arette n'importe ou et ce n'est vraiment pas propre...
Cela m'amène des érreurs aléatoire suivant ou la thread en était.

Publié : mar. 26/juil./2005 12:37
par gansta93
Donc il faudrait que lorsque le thread s'arrête, que les images soient fermées, puis tu utilise KillThread() pour l'arrêter.

Publié : mar. 26/juil./2005 13:14
par olivier
Merci Gansta pour tes réponses.

Je ne cherche pas d'autre solutions pour l'instant. Je veux que la thread me renvoie la confirmation de son arret.

Bref mon code corrigé.

Merci d'avance

Publié : mar. 26/juil./2005 14:07
par gansta93
Si j'ai bien compris, c'est une variable qui te confirme cela. Mais il me semble qu'elle n'est pas en global, essais donc de mettre cette variable en Global pour qu'elle puisse être utilisable partout. En espèrant que cette fois-là, ça t'aidera.

Publié : mar. 26/juil./2005 16:58
par olivier
ben si elle est en global ????? :mad:

Publié : mar. 26/juil./2005 21:22
par nico
Le repeat until en case 2 a pour conséquence la suspension du fonctionnement du thread, c'est curieux je trouve. En tout cas il faut supprimer cette boucle!

Publié : mer. 27/juil./2005 7:38
par olivier
He bien oui c'est curieux je trouve aussi !!!

Si je supprime cette boucle, quel moyen me donne tu pour détecter la fin complete de la thread ???

Publié : mer. 27/juil./2005 9:49
par nico
L'envoie d'un message par exemple:

Code : Tout sélectionner

Global fin_thread 

Procedure creer_vignette_thread(ess) 
  i=1 
  Repeat 
    i=i+1 
    Delay(100) 
    SetGadgetText(4,Str(i)) 
    
  Until i=10000 Or fin_thread=1 
  info1=i
  PostMessage_(WindowID(0),#WM_User+1,info1,Info2) 
EndProcedure 

If OpenWindow(0,10,10, 150, 300, #PB_Window_SystemMenu ,"memory") 
  If CreateGadgetList(WindowID(0)) 
    ButtonGadget(1, 50, 75, 100, 20, "compteur" ,#PB_Button_Default) 
    ButtonGadget(2, 50, 120, 100, 20, "stop compteur" ,#PB_Button_Default) 
  EndIf 
  
  
  Repeat 
    EventID.l = WaitWindowEvent() 
    
    Select  EventID 
      Case #PB_EventGadget 
        Select EventGadgetID() 
          Case 1 
            OpenWindow(3,200,100, 300, 200, #PB_Window_SystemMenu ,"ess") 
            If CreateGadgetList(WindowID()) 
              
              TextGadget(4, 10, 10,250,20,"compteur") 
              
            EndIf 
            CreateThread(@creer_vignette_thread(),ess)
            DisableGadget(1,1)
            
          Case 2
            DisableGadget(2,1)
            fin_thread=1 

            
        EndSelect
        
      Case #WM_User+1
        info1=EventwParam():Debug info1
        Info2=EventlParam()
        fin_thread=0
        DisableGadget(1,0)
        DisableGadget(2,0)
        MessageRequester("alerte","fin thread",0) 
        
      Case#PB_EventCloseWindow 
        If EventWindowID() = 0 
          Final.l = 1 
          CloseWindow(0) 
          CloseWindow(3) 
        Else 
          CloseWindow(3) 
        EndIf 
        
    EndSelect      
  Until Final.l = 1 
  
EndIf 
End 

Publié : mer. 27/juil./2005 10:42
par olivier
Merci Nico j'adapte cette solution comme cela

Code : Tout sélectionner


Global fin_thread

Procedure creer_vignette_thread(ess)
    i=1
    Repeat
        i=i+1
        Delay(100)
        SetGadgetText(4,Str(i))
        
    Until i=10000 Or fin_thread=1
    
    fin_thread=2
EndProcedure

If OpenWindow(0,10,10, 150, 300, #PB_Window_SystemMenu ,"memory")
    If CreateGadgetList(WindowID(0))
        ButtonGadget(1, 50, 75, 100, 20, "compteur" ,#PB_Button_Default)
        ButtonGadget(2, 50, 120, 100, 20, "stop compteur" ,#PB_Button_Default)
    EndIf
    
    
    Repeat
        EventID.l = WindowEvent()
        Delay(10)
        If fin_thread=2 : MessageRequester("alerte","fin thread",0): fin_thread=0 : CloseWindow(3): EndIf
        
        If EventID = #PB_EventGadget
            Select EventGadgetID()
                Case 1
                    OpenWindow(3,200,100, 300, 200, #PB_Window_SystemMenu ,"ess")
                    If CreateGadgetList(WindowID())
                        
                        TextGadget(4, 10, 10,250,20,"compteur")
                        
                    EndIf
                    CreateThread(@creer_vignette_thread(),ess)
                Case 2
                    fin_thread=1

            EndSelect
        EndIf
        
        If EventID = #PB_EventCloseWindow
            If EventWindowID() = 0
                Final.l = 1
                CloseWindow(0)
                CloseWindow(3)
            Else
                CloseWindow(3)
            EndIf
            
            
        EndIf
    Until Final.l = 1
    
EndIf
End


Cela résoud le problème, mais ce n'est pas tres jolie et ne répond pas à la question : Pourquoi la thread se bloque lors de la boucle avec delay() ?

Mais merci encore Nico, cela va pouvoir résoudre mon problème.

a+

Publié : mer. 27/juil./2005 11:44
par nico
Oh la la, j'éviterais de coder de cette façon là!