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,
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....
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

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

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

Re: SetGadgetState effroyablement lent...
Publié : mer. 21/août/2019 13:39
par SPH
Je ne comprend rien
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
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