Page 1 sur 2

SetGadgetState ou ReadQuad lent au bout d'un moment...

Publié : mar. 20/août/2019 15:48
par SPH
Voir mon dernier post

Salut, 8)

j'ai essayé SetGadgetState(99, a) et je constate qu'il prend un temps effroyable dans une boucle (enorme) !!!
Alors, j'essaye de l'executer en parallèle mais je n'y comprend rien.
Je voudrais que toutes les 4 secondes, le SetGadgetState(99, a) s'actualise (sans qu'il soit dans la boucle) : c'est le role d'un thread je crois...

Voici le code qui ne fonctinnera pas car il manque tous les dim() et autres.... :idea:

Code : Tout sélectionner

Procedure AlertThread2(a)
SetGadgetState   (99, a)
EndProcedure

ProgressBarGadget(99,  13, 619, 722,  15, 0, longueur_q-1)
thread =CreateThread(@AlertThread2(), a)
If thread
For a=0 To longueur_q-1  ; ecriture d'un fichier de (781250 ko soit lus de 781Mo)
  ;SetGadgetState(99, a)                       ;;;;;;  
  x=Random(Len(mdp3$))+1
  quad_hazard.q=octets1(x)+octets1(x+1)*256+octets1(x+2)*65536+octets1(x+3)*16777216+octets1(x+4)*4294967296+octets1(x+5)*1099511627776+octets1(x+6)*281474976710656+octets1(x+7)*72057594037927936
  ;   ici2=Random(Len(mdp3$)-10)
  x=Random(Len(sph$))+1
  quad_hazard.q!octets2(x)+octets2(x+1)*256+octets2(x+2)*65536+octets2(x+3)*16777216+octets2(x+4)*4294967296+octets2(x+5)*1099511627776+octets2(x+6)*281474976710656+octets2(x+7)*72057594037927936
  
  ;   a$="$"+Mid(sph$,ici1,16)
  ;   quad_hazard.q=Val(a$)
  ;   a$="$"+Mid(mdp3$,ici2,16)
  ;   quad_hazard.q=Val(a$)
  
  ;;;;;
  
  tableau(a)!quad_hazard
  q=Random(65536*32768-1)+cent(Random(100))
  q*Random(65536*32768-1)*vingt(Random(20)+1)
  q*Random(65536*32768-1)*vingt(Random(20)+1)
  q*Random(65536*32768-1)+vingt(Random(20)+1)
  q*Random(65536*32768-1)+vingt(Random(20)+1)
  q+Random(65536*32768-1)+cent(Random(100))
  q+Random(65536*32768-1)+cent(Random(100))
  tableau(a)!q
  
  WriteQuad(0, tableau(a));                                                                      ########
  
Next a
EndIf

Re: SetGadgetState effroyablement lent...

Publié : mar. 20/août/2019 16:51
par Ar-S
Donne un code viable, minimal, avec une fenêtre et le gadget en question..
Je voudrais que toutes les 4 secondes, le SetGadgetState(99, a) s'actualise (sans qu'il soit dans la boucle) : c'est le role d'un thread je crois...
Non, un thread est là pour exécuter une opération (lourde sinon l'intérêt est moindre) en évitant de figer la fenêtre principale qui utilise son propre thread.
Toutes les 4 sec


Exemple de Timer

Code : Tout sélectionner

If OpenWindow(0, 0, 0, 400, 100, "Exemple Minuteur", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    StringGadget(0, 10, 10, 380, 20, "")
    
    ; Ajout du minuteur n°123 dans la fenêtre 0 qui se déclenchera toutes les 250 ms
    AddWindowTimer(0, 123, 1000)
    
    Value = 0
    Repeat
      Event = WaitWindowEvent()
      
      If Event = #PB_Event_Timer And EventTimer() = 123
        Seconde + 1
        SetWindowTitle(0, Str(seconde))
        If Seconde = 4
          SetGadgetText(0, "Coucou")
          seconde = 0
        Else
          SetGadgetText(0, "~~~~~XD~~~~~")
        EndIf
        
      EndIf    
      
    Until Event = #PB_Event_CloseWindow
  EndIf
Ensuite (au cas ou) pense à désactiver le debug si tu demandes des taches complexes au programme.

- Code principale
- DisableDebugger
- opération lourde
- enableDebugger
- suite du code

Re: SetGadgetState effroyablement lent...

Publié : mar. 20/août/2019 17:12
par SPH
Merci, je matte ca sous peu :idea:

Re: SetGadgetState effroyablement lent...

Publié : mar. 20/août/2019 18:10
par venom
Tu souhaite faire avancer une ProgressBar apparemment.

Voici un code de falsam tu peux t'en inspiré :

Code : Tout sélectionner

;ATTENTION : Ce code est à compiler avec l'option Thread dans les directives de compilation
;Falsam
;Menu Compilateur => Option du compilateur => Activer la gestion des threads

;Travailler avec des constantes c'est plus lisibles que des numéros
Enumeration Window
  #mf
EndEnumeration

Enumeration Gadget
  #mfOnOff
  #mfListFolder
  #mfCountFiles
  #mfProgress
EndEnumeration

;Déclaration des variables
Global OnOff.b        ;Interupteur OnOff (#True, #False)
Global CountFiles.i   ;Compteur de fichiers

;Plan application
Declare   Start()
Declare   OnOff()
Declare   StartThread(*Value)
Declare.s ParseDirectory(folder.s, id.l = 0)
Declare   Resize()
Declare   Exit()

;Appel de la procédure Start
Start()

;Affichage de l'application
Procedure Start()
 
  ;Creation de la fenetre
  OpenWindow(#mf, 0, 0, 400, 320,"Lecture d'un dossier(Thread)",#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget)
 
  ;On evite le chevauchements des gadgets en donnant une taille minimum à la fenetre
  WindowBounds(#mf, 300, 320, #PB_Ignore, #PB_Ignore)
   
  ;Création des gadgets
  TextGadget(#PB_Any, 5, 10, 120, 20, "Nombre de fichiers lus")
  TextGadget(#mfCountFiles, 130, 10, 80, 20, "0", #PB_Text_Right)
  ListIconGadget(#mfListFolder, 5, 30, 390,250, "Dossier", 200)
  AddGadgetColumn(#mfListFolder, 1, "Fichiers",200)
  ProgressBarGadget(#mfProgress, 5, 290, 200, 24, 0, 10000)
  ButtonGadget(#mfOnOff, 325, 290, 70, 24, "On/Off")
 
  ;Gestion des evenements
  BindGadgetEvent(#mfOnOff, @OnOff())        ;Si clique sur le bouton OnOff, appel de la procedure OnOff
  BindEvent(#PB_Event_SizeWindow, @Resize()) ;Redimentionner les gadgets de la fenêtre
  BindEvent(#PB_Event_CloseWindow, @Exit())  ;Si fermeture alors appel à la procedure Exit()
 
  Repeat : WaitWindowEvent(10) : ForEver
EndProcedure

;Procédure appelée quand on clique sur le bouton
Procedure OnOff()
  Static Thread
 
  If OnOff = #False
    ClearGadgetItems(#mfListFolder)
    CountFiles=0
    OnOff = #True
    Thread = CreateThread(@StartThread(), 0)
  Else
    OnOff = #False
  EndIf
EndProcedure

Procedure StartThread(*Value)
  ;On lance la lecture des fichiers
  ParseDirectory(GetEnvironmentVariable("USERPROFILE"))
 
  ;Une boucle d'attente quand que la variable OnOff reste à #True
  While OnOff = #True : Wend
EndProcedure

;Parcourir un dossier (Fonction recurssive by Flype il me semble)
Procedure.s ParseDirectory(folder.s, id.l = 0)
  If Right(folder, 1) <> "\"
    folder + "\"
  EndIf
 
  If ExamineDirectory(id, folder, "*.*")
    While NextDirectoryEntry(id) And OnOff = #True
      If DirectoryEntryName(id) <> "." And DirectoryEntryName(id) <> ".."
        AddGadgetItem(#mfListFolder,-1, folder + Chr(10) + DirectoryEntryName(id))
       
        ;Mise à jour du compteur de fichier lu (On s'arrete à 10 000 fichiers
        countFiles + 1
       
        ;Mettre à jour le ProgressBar (Inutile de le créer à nouveau)
        SetGadgetState(#mfProgress, countFiles)
        If CountFiles >= 10000
          OnOff()
        EndIf
       
        ;Affichage du coompteur de fichiers (Inutile de le créer à nouveau)
        SetGadgetText(#mfCountFiles, Str(CountFiles))
       
        If DirectoryEntryType(id) = #PB_DirectoryEntry_Directory
          ParseDirectory(folder + DirectoryEntryName(id), id + 1)
        EndIf
      EndIf
    Wend
    FinishDirectory(id)
  EndIf
EndProcedure

Procedure Resize()
  Protected WWidth=WindowWidth(#mf)
  Protected Wheight=WindowHeight(#mf)
  ResizeGadget(#mfListFolder, #PB_Ignore, #PB_Ignore , WWidth-10, Wheight-75)
  ResizeGadget(#mfProgress, #PB_Ignore, Wheight-30 , #PB_Ignore, #PB_Ignore) 
  ResizeGadget(#mfOnOff, WWidth - 75, Wheight-30 , #PB_Ignore, #PB_Ignore)
EndProcedure

Procedure Exit()
  End 
EndProcedure





@++

Re: SetGadgetState effroyablement lent...

Publié : mar. 20/août/2019 18:19
par SPH
Merci a toi aussi. Je regarde ca quand je serais sur l'autre ordi :wink:

Re: SetGadgetState effroyablement lent...

Publié : mar. 20/août/2019 20:41
par Ar-S
@Venom (et aux autres)
Petit rappel. Pour ne pas oublier de compiler avec la gestion des threads activée dans vos codes (surtout si vous les partagez), vous pouvez ajouter ce petit bout de code au début de votre programme.

Code : Tout sélectionner

If #PB_Compiler_Thread = 0
  MessageRequester("Attention","Vous devez activer la gestion des Threads dans les options de compilation",#PB_MessageRequester_Warning)
  End  
EndIf

Re: SetGadgetState effroyablement lent...

Publié : mar. 20/août/2019 21:03
par venom
Falsam l'a spécifié (la première ligne du code)
Mais c'est vrai que ton bout de code est sympa.
Merci du partage.







@++

Re: SetGadgetState effroyablement lent...

Publié : mer. 21/août/2019 10:14
par microdevweb
@SPH,

Voici une exemple avec un thread, je l'ai réglé sur une seconde, mais tu peux le changer à ton goût. Pendant le traitement essaye de quitter la fenêtre et tu constateras que l'avantage d'un thread est qu'il n'est pas bloquant

Code : Tout sélectionner

; petit exemple avec un thread
Global myThread

Procedure refresh(*para)
  Static started ; temps du lancement
  Repeat
    If ElapsedMilliseconds() - started >= 999 ; 1 seconde 1000 -1 pour le petit delay place 3999 pour tes 4 secondes
      started = ElapsedMilliseconds()
      SetGadgetState(0,GetGadgetState(0)+1)
      SetGadgetText(1,Str(GetGadgetState(0))+" %")
      If GetGadgetState(0) >= 100
        Debug "the threadh was killed"
        KillThread(myThread)
      EndIf
    EndIf
    Delay(1) ; important il faut placer un petit delay
  ForEver
EndProcedure

Procedure exit()
  ; on quite proprement
  If IsThread(myThread)
    PauseThread(myThread)
    If MessageRequester("Arrêt du processus","Etes-vous sure?",#PB_MessageRequester_YesNo)=#PB_MessageRequester_Yes
      KillThread(myThread)
    Else
      ResumeThread(myThread)
      ProcedureReturn ; pour ne pas fermer la fenêtre
    EndIf
  EndIf
  CloseWindow(0)
  End
EndProcedure


OpenWindow(0,0,0,800,600,"Teste",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
TextGadget(1,10,240,780,30,"",#PB_Text_Center)
ProgressBarGadget(0,10,290,780,40,0,100)
BindEvent(#PB_Event_CloseWindow,@exit())
myThread = CreateThread(@refresh(),0)

Repeat: WaitWindowEvent() : ForEver




Re: SetGadgetState effroyablement lent...

Publié : mer. 21/août/2019 13:07
par SPH
Merci Micro :wink:

Re: SetGadgetState effroyablement lent...

Publié : mer. 21/août/2019 13:39
par SPH
Je ne comprend rien :oops: :oops: :oops:
Voici un exemple TRES simple :

Code : Tout sélectionner

longueur_q=50000000



For a=0 To longueur_q
    
    
    quad_hazard2.q=q!quad_hazard
    q=Random(65536*32768-1)
    q*Random(65536*32768-1)
    q*Random(65536*32768-1)
    q*Random(65536*32768-1)
    q*Random(65536*32768-1)
    q+Random(65536*32768-1)
    q+Random(65536*32768-1)
    quad_hazard2!q
    
    
  Next a
 
Comment y inserer un ProgressBarGadget qui tourne en paralelle mais sans ralentir la boucle ?

Re: SetGadgetState effroyablement lent...

Publié : mer. 21/août/2019 14:00
par microdevweb
@sph,

Tu veux afficher quoi dans ton progresse bar ?

Re: SetGadgetState effroyablement lent...

Publié : mer. 21/août/2019 15:13
par SPH
microdevweb a écrit :@sph,

Tu veux afficher quoi dans ton progresse bar ?
Bin, en l'occurence, ce serait ca :

Code : Tout sélectionner

longueur_q=50000000

ProgressBarGadget(99,  13, 619, 722,  15, 0, longueur_q)

For a=0 To longueur_q
    
    
    quad_hazard2.q=q!quad_hazard
    q=Random(65536*32768-1)
    q*Random(65536*32768-1)
    q*Random(65536*32768-1)
    q*Random(65536*32768-1)
    q*Random(65536*32768-1)
    q+Random(65536*32768-1)
    q+Random(65536*32768-1)
    quad_hazard2!q
    
    
  Next a
 

Re: SetGadgetState effroyablement lent...

Publié : mer. 21/août/2019 20:53
par Ar-S
Franchement tu n'aides pas à la compréhension.

Tu veux quoi exactement ?
Parce que je vois mal ton prog afficher le resultat de Q ou de quad_hazard2 dans une Progresse bar....

Qu'est-ce qui doit s'afficher ?
Dans quel sorte de gadget ?
Tous les combien ? (4 sec à ce que j'ai compris)
Et pendant combien de temps ?

Re: SetGadgetState effroyablement lent...

Publié : mer. 21/août/2019 21:49
par SPH

Code : Tout sélectionner

longueur_q=50000000

ProgressBarGadget(99,  13, 619, 722,  15, 0, longueur_q)

For a=0 To longueur_q
    
    
    quad_hazard2.q=q!quad_hazard
    q=Random(65536*32768-1)
    q*Random(65536*32768-1)
    q*Random(65536*32768-1)
    q*Random(65536*32768-1)
    q*Random(65536*32768-1)
    q+Random(65536*32768-1)
    q+Random(65536*32768-1)
    quad_hazard2!q
    
    
  Next a
Je veux donc que la ProgressBarGadget(99, 13, 619, 722, 15, 0, longueur_q) aille progressivement de 0 à longueur_q (réactualisé toutes les 3 ou 4 secondes)

Désolé, je peux pas etre plus clair :oops:

Quant à mes "q+Random(65536*32768-1)", ils sont là pour alourdir la boucle. C'est fait exprès :!:

Re: SetGadgetState effroyablement lent...

Publié : mer. 21/août/2019 22:20
par TazNormand
@SPH : ton raisonnement est un peu foireux car tu pars du principe que ta ProgressBar doit aller jusqu'à longueur_q.

Je pense qu'il vaut mieux faire un prorata sur 100 pour que ta barre avance par pas successifs.

le gadget ProgressBar n'accepte que des valeurs maxi jsq 65536 (cf la doc), donc si tu veux que ta barre avance progressivement jusqu'à ce que ta boucle arrive à longueur_q, il faut utiliser un ratio :
=> ta progressBar a une valeur maxi de 100
=> à chaque itération de ta boucle, la progressbar ne doit pas avancer de la valeur de l'indice de boucle (variable a dans ton code), mais du ratio ((a/longueur_q)*100)
=> quand "a" vaudra 250 000 tu seras bien à 50% de ta progressBar (250 000/500 000 = 1/2 = 0.5) et multiplié par 100 = 50
=> quand "a" vaudra longueur_q, soit 500 000, tu auras (500 000/500 000 = 1/1 = 1) et multiplié par 100 = 100 donc 100%

Perso je trouve que travailler avec des indicateurs de progression est plus simple en se basant sur du pourcentage que sur les valeurs réelles, la preuve avec ton valeur_q qui est plus grand que ce qu'accepte le gadget ProgressBar