OVH Cloud OVH Cloud

Timer sans pause

8 réponses
Avatar
TouTi
Bonjour

J'aimerai créer un timer (en lui passant des paramètres) sans qu'il ne
provoque une pause dans le déroulement d'une function.

Je m'explique...
Dans une function je gére des événements complétement aléatoires.
Selon ces types d'événements(appelés EV) j'aimerai déclencher des actions
temporisées sans créer de pause dans la fonctions. exemple :
function gereEV()
code
si EV = 1 alors action-1 dans 110 msecondes
si EV = 2 alors action-2 dans 3000 msecondes
...
code
end function


actuellement, les actions sont déclenchées dans la function ce qui crée une
pause dans son déroulement.
Sub Delay(vdp As Single)
tdps = Timer
While (tdps + vdp) > Timer
DoEvents
Wend
End Sub
Function gereEV()
code
si EV = 1 alors delay(0.11) : action-1
si EV = 2 alors delay(3) : action-2
...
code
end function


Avec quoi et comment puis-je arriver à mes fins???

merci

--
Guy

8 réponses

Avatar
Jean-marc
"TouTi" <gelapplication[NsP]@tiscali.fr> a écrit dans le message de news:
uxX8A8$$
Bonjour

J'aimerai créer un timer (en lui passant des paramètres) sans qu'il ne
provoque une pause dans le déroulement d'une function.

Je m'explique...
Dans une function je gére des événements complétement aléatoires.
Selon ces types d'événements(appelés EV) j'aimerai déclencher des actions
temporisées sans créer de pause dans la fonctions. exemple :
function gereEV()
code
si EV = 1 alors action-1 dans 110 msecondes
si EV = 2 alors action-2 dans 3000 msecondes
...
code
end function


actuellement, les actions sont déclenchées dans la function ce qui crée
une pause dans son déroulement.
Sub Delay(vdp As Single)
tdps = Timer
While (tdps + vdp) > Timer
DoEvents
Wend
End Sub
Function gereEV()
code
si EV = 1 alors delay(0.11) : action-1
si EV = 2 alors delay(3) : action-2
...
code
end function


Avec quoi et comment puis-je arriver à mes fins???




Hello,

Très intéressant. Une solution assez élégante serait
d'instancier dynamiquement des controles Timer, et de
gérer un tableau d'évènements. Une procédure centralisé
serait appelé par chaque timer au moment choisi. Chaque
timer se charge de positionner la bonne valeur au bon endroit
dans le tableau des évènements.

Je vais essayer de te faire un petit bout de code d'exemple.

--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
mailto: remove '_no_spam_' ;
FAQ VB: http://faq.vb.free.fr/
Avatar
Jean-marc
"Jean-marc" a écrit dans le message
de news: 454c9725$0$21493$
"TouTi" <gelapplication[NsP]@tiscali.fr> a écrit dans le message de news:
uxX8A8$$
Bonjour

J'aimerai créer un timer (en lui passant des paramètres) sans qu'il ne
provoque une pause dans le déroulement d'une function.

Je m'explique...
Dans une function je gére des événements complétement aléatoires.
Selon ces types d'événements(appelés EV) j'aimerai déclencher des actions
temporisées sans créer de pause dans la fonctions. exemple :
function gereEV()
code
si EV = 1 alors action-1 dans 110 msecondes
si EV = 2 alors action-2 dans 3000 msecondes
...
code
end function


actuellement, les actions sont déclenchées dans la function ce qui crée
une pause dans son déroulement.
Sub Delay(vdp As Single)
tdps = Timer
While (tdps + vdp) > Timer
DoEvents
Wend
End Sub
Function gereEV()
code
si EV = 1 alors delay(0.11) : action-1
si EV = 2 alors delay(3) : action-2
...
code
end function


Avec quoi et comment puis-je arriver à mes fins???






Re hello,


Voila,

il n'y a finalement même pas besoin d'un tableau d'evenements,
juste instancier dynamiquement des Timer.

Pour faire fonctionner le code suivant (exemple), il faut:
- un projet avec un form nommé form1
- 3 boutons de commandes, Command1, Command2, Command3
- Un timer nommé Timer1, avec propriété index à 0 (tres important)

Copier le code ci dessous dans le Form


Option Explicit

Private Const NB_MAX_TIMER As Long = 20
Private TTimers(NB_MAX_TIMER) As Integer

Private Function GetFreeTimer() As Long
Dim i As Long
Dim Index As Integer

Index = -1
For i = 1 To NB_MAX_TIMER
If TTimers(i) = 0 Then
TTimers(i) = 1
Index = i
Exit For
End If
Next i
GetFreeTimer = Index

End Function

Private Sub Command1_Click()
Dim bRet As Boolean

MsgBox "EVENEMENT 1, action 1 souhaitéee dans 5 secondes"
bRet = HandleTimerEV(5, 1)
If Not bRet Then MsgBox "probleme"
End Sub

Private Sub Command2_Click()
Dim bRet As Boolean

MsgBox "EVENEMENT 2, action 2 souhaitéee dans 3 secondes"
bRet = HandleTimerEV(3, 2)
If Not bRet Then MsgBox "probleme"
End Sub

Private Sub Command3_Click()
Dim bRet As Boolean

MsgBox "EVENEMENT 3, action 3 souhaitéee dans 8 secondes"
bRet = HandleTimerEV(8, 3)
If Not bRet Then MsgBox "probleme"
End Sub


'
' delay en secondes
'
Private Function HandleTimerEV(delay As Double, evNumber As Long) As Boolean
Dim t As Long

t = GetFreeTimer()
If t <> -1 Then
Load Timer1(t)
Timer1(t).Tag = evNumber
Timer1(t).Interval = 1000 * delay
Timer1(t).Enabled = True
HandleTimerEV = True
Else
MsgBox "plus de timer disponibles"
HandleTimerEV = False
End If
End Function

Private Sub Form_Load()

End Sub

Private Sub Timer1_Timer(Index As Integer)
' cet evenement a fini son delai
'déclenche l'appel
Call GestionnaireEvenements(Timer1(Index).Tag)
'libère ce controle
TTimers(Index) = 0
' et décharge
Unload Timer1(Index)
End Sub

Private Sub GestionnaireEvenements(evNumber As Long)

Select Case evNumber
Case 1:
MsgBox "Suite à évènement 1, action 1"
Case 2:
MsgBox "Suite à évènement 2, action 2"
Case 3:
MsgBox "Suite à évènement 3, action 3"
End Select
End Sub




La fonction qui fait tout le travail est:
HandleTimerEV(delay As Double, evNumber As Long)
=>on donne le delay et le numéro d'evenement

La fonction qui sera alors automatiquement appelé est:
Private Sub GestionnaireEvenements(evNumber As Long)
Elle est appelé après le délai demandé avec le numéro d'évènement.


Pour jouer avec le code d'exemple, appuyer simplement sur les boutons.
On peut déclencher plusiers fois le même évènement, on peut
les déclencher dans n'importe quel ordre, à n'importe quelle
fréquence.

Et bien sur, tout est parafitement asynchrone et uniquement
"event driven": pas de boucles, pas d'attentes, pas de polling.

Pour info, c'est avec ce genre de techniques qu'on gère un serveur
qui reçoit des demandes de connections asynchrones. On instancie
dynamiquement des sockets en fonction des demandes.

--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
mailto: remove '_no_spam_' ;
FAQ VB: http://faq.vb.free.fr/
Avatar
TouTi
>>> J'aimerai créer un timer (en lui passant des paramètres) sans qu'il ne
provoque une pause dans le déroulement d'une function.







Et bien sur, tout est parafitement asynchrone et uniquement
"event driven": pas de boucles, pas d'attentes, pas de polling.



Ouaaahhhhh que du bonheur....

Un grand merci jean-marc pour ta rapidité, ton analyse, ta production, tes
commentaires

Encore une petite question... est-on vraiment limité à 20 timers??? En fait
je gère un flux de circulation où tous les 500 millisecondes il peut y avoir
bien plus d'actions à réaliser.


a++

--
Guy
Avatar
Jean-marc
"TouTi" <gelapplication[NsP]@tiscali.fr> a écrit dans le message de news:
%
J'aimerai créer un timer (en lui passant des paramètres) sans qu'il ne
provoque une pause dans le déroulement d'une function.







Et bien sur, tout est parafitement asynchrone et uniquement
"event driven": pas de boucles, pas d'attentes, pas de polling.





Hello,

Ouaaahhhhh que du bonheur....



Un grand merci jean-marc pour ta rapidité, ton analyse, ta production, tes
commentaires



Avec plaisir.

Encore une petite question... est-on vraiment limité à 20 timers??? En
fait je gère un flux de circulation où tous les 500 millisecondes il peut
y avoir bien plus d'actions à réaliser.




Non bien sur! Ce n'est qu'un exemple!
Tu peux en instancier un grand nombre, je ne sais pas
si il y a une limite, mais je sais que j'ai déjà fait des essais
avec plus de 200 instances dynamiques.

Si j'ai 5 minutes, je ferais un test pour voir si il ya une limite.


--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
mailto: remove '_no_spam_' ;
FAQ VB: http://faq.vb.free.fr/
Avatar
Jean-marc
"TouTi" <gelapplication[NsP]@tiscali.fr> a écrit dans le message de news:
%
J'aimerai créer un timer (en lui passant des paramètres) sans qu'il ne
provoque une pause dans le déroulement d'une function.







Et bien sur, tout est parafitement asynchrone et uniquement
"event driven": pas de boucles, pas d'attentes, pas de polling.



Ouaaahhhhh que du bonheur....

Un grand merci jean-marc pour ta rapidité, ton analyse, ta production, tes
commentaires

Encore une petite question... est-on vraiment limité à 20 timers??? En
fait je gère un flux de circulation où tous les 500 millisecondes il peut
y avoir bien plus d'actions à réaliser.



Re,

voila j'ai fait un test: Ca a crashé après avoir
instancié 9777 Timer...

Je pense que si tu restes en dessous de 1000, tu n'auras
pas de soucis :o)

--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
mailto: remove '_no_spam_' ;
FAQ VB: http://faq.vb.free.fr/
Avatar
TouTi
Jean Marc

voila j'ai fait un test: Ca a crashé après avoir
instancié 9777 Timer...

Je pense que si tu restes en dessous de 1000, tu n'auras
pas de soucis :o)



Oui bah là ça devrait le faire...

Il ne me reste plus qu'à gérer le passage des paramètres pour les
actions....
Tient.... tant que je t'ai sous la main et que tu me sembles fort à ton aise
:-)) que penses-tu de ma technique : Il n'y aurait-il pas plus simple
(surtout dans GestionnaireEvenements)

Disons que j'envoie :
Tps_Par = NumAction & ":" & NumEng & "[" & ctc & "]" & "$" & dirx & "+" &
diry
bRet = HandleTimerEV( 2, Para)

Private Function HandleTimerEV(delay As Double, Para As String) As Boolean
Dim t As Long
t = GetFreeTimer()
If t <> -1 Then
Load Timer1(t)
Timer1(t).Tag = Para
Timer1(t).Interval = 1000 * delay
Timer1(t).Enabled = True
HandleTimerEV = True
Else
MsgBox "plus de timer disponibles"
HandleTimerEV = False
End If
End Function

au déclenchement
Private Sub GestionnaireEvenements(Para As String)
depo = InStr(1, Para , ":")
croo = InStr(depo + 1, Para , "[")
crof = InStr(croo + 1, Para , "]")

If depo > 0 and croo>0 and crof > Then
evNumber = Val(left(Para , depo - 1))
nloco = Val(Mid(Para , depo + 1, croo - depo - 1))
ctc = Val(Mid(Para , croo + 1, crof - croo - 1))
dloco = Mid(Para , crof + 1)
Select Case evNumber
Case 1: Call posloco nloco, ctc, dloco, -1, ""
Case 2: MsgBox "Suite à évènement 2, action 2"
Case 3: MsgBox "Suite à évènement 3, action 3"
End Select
end if
End Sub

A++

--
Guy
Avatar
Jean-marc
Hello,

oui je pense qu'il y a plus simple. Pourquoi ne
pas par exemple séparer toutes les valeurs par une virgule,
et récuprérer les éléments avec la fonction Split().

Ca marche comme ça:

Private Sub Command1_Click()
' ancien format: "3:12[34]$123+456"
' nouveau format :
Call toto("3,12,34,123+256")
End Sub

Private Sub toto(para As String)
Dim evNumber As Long
Dim nLoco As Long
Dim ctc As Long
Dim dLoco As String
Dim t() As String

t() = Split(para, ",")
evNumber = CLng(t(0))
nLoco = CLng(t(1))
ctc = CLng(t(2))
dLoco = t(3)
End Sub


Plus simple, non?

--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
mailto: remove '_no_spam_' ;
FAQ VB: http://faq.vb.free.fr/

"TouTi" <gelapplication[NsP]@tiscali.fr> a écrit dans le message de news:
OJoOI%
Jean Marc

voila j'ai fait un test: Ca a crashé après avoir
instancié 9777 Timer...

Je pense que si tu restes en dessous de 1000, tu n'auras
pas de soucis :o)



Oui bah là ça devrait le faire...

Il ne me reste plus qu'à gérer le passage des paramètres pour les
actions....
Tient.... tant que je t'ai sous la main et que tu me sembles fort à ton
aise :-)) que penses-tu de ma technique : Il n'y aurait-il pas plus
simple (surtout dans GestionnaireEvenements)

Disons que j'envoie :
Tps_Par = NumAction & ":" & NumEng & "[" & ctc & "]" & "$" & dirx & "+" &
diry
bRet = HandleTimerEV( 2, Para)

Private Function HandleTimerEV(delay As Double, Para As String) As Boolean
Dim t As Long
t = GetFreeTimer()
If t <> -1 Then
Load Timer1(t)
Timer1(t).Tag = Para
Timer1(t).Interval = 1000 * delay
Timer1(t).Enabled = True
HandleTimerEV = True
Else
MsgBox "plus de timer disponibles"
HandleTimerEV = False
End If
End Function

au déclenchement
Private Sub GestionnaireEvenements(Para As String)
depo = InStr(1, Para , ":")
croo = InStr(depo + 1, Para , "[")
crof = InStr(croo + 1, Para , "]")

If depo > 0 and croo>0 and crof > Then
evNumber = Val(left(Para , depo - 1))
nloco = Val(Mid(Para , depo + 1, croo - depo - 1))
ctc = Val(Mid(Para , croo + 1, crof - croo - 1))
dloco = Mid(Para , crof + 1)
Select Case evNumber
Case 1: Call posloco nloco, ctc, dloco, -1, ""
Case 2: MsgBox "Suite à évènement 2, action 2"
Case 3: MsgBox "Suite à évènement 3, action 3"
End Select
end if
End Sub

A++

--
Guy



Avatar
TouTi
> oui je pense qu'il y a plus simple. Pourquoi ne
pas par exemple séparer toutes les valeurs par une virgule,
et récuprérer les éléments avec la fonction Split().

Plus simple, non?



Oui quand même ....

Merci et bon WE

--
Guy