OVH Cloud OVH Cloud

Timer précis

3 réponses
Avatar
Thierry S
Bonjour à tous,
J'ai développé une application en VB.NET qui contient entre autre 2 objets
Timer qui fonctionnent indépendamment l'un de l'autre. Mais je me suis
apperçu que les timers n'étaient pas très précis. Ils sont réglés tous les
deux sur 400ms mais par moment il dure plus longtemps.
Que pourrais-je utiliser d'autre de plus précis et qui ne bloque pas toute
l'appli pendant les 400ms?
Je vous en remercie d'avance.

3 réponses

Avatar
Osman MALIK [MS]
Bonjour,

Pourriez vous me donner plus d'informations sur votre besoin exact?
Est-ce que vous désirez lancer plusieurs timers pour piloter plusieurs
opérations?
Si c'est le cas, ne vous est-il pas possible de n'utiliser qu'un seul timer?

Enfin, si vous désirez pouvoir réaliser le calcul des délais de manière plus
précise (.1 milliseconde), vous trouverez un article traitant de cet aspect
ici:
http://www.eggheadcafe.com/articles/20021111.asp

Cordialement,

Osman MALIK [MS France]



"Thierry S" wrote in message
news:
Bonjour à tous,
J'ai développé une application en VB.NET qui contient entre autre 2 objets
Timer qui fonctionnent indépendamment l'un de l'autre. Mais je me suis
apperçu que les timers n'étaient pas très précis. Ils sont réglés tous les
deux sur 400ms mais par moment il dure plus longtemps.
Que pourrais-je utiliser d'autre de plus précis et qui ne bloque pas toute
l'appli pendant les 400ms?
Je vous en remercie d'avance.



Avatar
Thierry S
Bonjour,
En fait c'est une application industrielle qui communique avec 2 machines et
2 appareils pour effectuer des mesures.
Une machine envoie un top à l'application qui elle envoie une demande de
mesure sur un appareil de mesure de la machine. Ensuite l'application doit
attendre 400ms avant d'aller lire les données dans l'appareil de mesure. Nous
avons en moyenne un top toutes les 500ms.
Chaque machine fonctionne indépendamment. Donc je peux très bien avoir les 2
tops en même temps que pas du tout.
Donc mon problème se situe au niveau de mes 2 timers de 400ms. Par moment
ils durent plus de 500ms (mesure avec QueryPerformanceCounter) ce qui me fait
louper des tops et donc des mesures.
Je vais aller regarder un plus près le lien que vous avez mis.

Merci.

"Osman MALIK [MS]" a écrit :

Bonjour,

Pourriez vous me donner plus d'informations sur votre besoin exact?
Est-ce que vous désirez lancer plusieurs timers pour piloter plusieurs
opérations?
Si c'est le cas, ne vous est-il pas possible de n'utiliser qu'un seul timer?

Enfin, si vous désirez pouvoir réaliser le calcul des délais de manière plus
précise (.1 milliseconde), vous trouverez un article traitant de cet aspect
ici:
http://www.eggheadcafe.com/articles/20021111.asp

Cordialement,

Osman MALIK [MS France]



"Thierry S" wrote in message
news:
> Bonjour à tous,
> J'ai développé une application en VB.NET qui contient entre autre 2 objets
> Timer qui fonctionnent indépendamment l'un de l'autre. Mais je me suis
> apperçu que les timers n'étaient pas très précis. Ils sont réglés tous les
> deux sur 400ms mais par moment il dure plus longtemps.
> Que pourrais-je utiliser d'autre de plus précis et qui ne bloque pas toute
> l'appli pendant les 400ms?
> Je vous en remercie d'avance.
>





Avatar
Zoury
Salut Thierry ! :O)

Le problème de précision vient du fait que les timers fournit avec le
Framework n'ont pas un niveau de priorité élévé et sont donc retardés par
les autres tâches jusqu'à ce que le système puisse enfin les exécuter.

Regarde du côté des timers Multimedia. Ils permettent de modifier la
résolution et sont très précis.
http://msdn.microsoft.com/library/en-us/multimed/htm/_win32_about_multimedia_timers.asp

Voici un exemple d'utilisation :
'***
' Class Timer
Option Explicit On

Imports System.Runtime.InteropServices
Imports System.ComponentModel

Public Class Timer
Implements IDisposable

Private Shared m_tc As TIMECAPS
Private m_uDelay As UInt32
Private m_uResolution As UInt32
Private m_uTimerID As UInt32
Public Event Callback As EventHandler

#Region " Déclarations APIs "

<Flags()> _
Private Enum EVENTFLAG : UInt32
TIME_ONESHOT = &H0
TIME_PERIODIC = &H1
TIME_CALLBACK_FUNCTION = &H0
TIME_CALLBACK_EVENT_SET = &H10
TIME_CALLBACK_EVENT_PULSE = &H20
TIME_KILL_SYNCHRONOUS = &H100
End Enum

Private Delegate Sub LPTIMECALLBACK( _
ByVal uID As UInt32, _
ByVal uMsg As UInt32, _
ByVal dwUser As Int32, _
ByVal dw1 As Int32, _
ByVal dw2 As Int32)

<StructLayout(LayoutKind.Sequential)> _
Private Structure TIMECAPS

Private m_uPeriodMin As UInt32
Private m_uPeriodMax As UInt32

Public Sub New(ByVal uPeriodMin As UInt32, ByVal uPeriodMax As
UInt32)
m_uPeriodMin = uPeriodMin
m_uPeriodMax = uPeriodMax
End Sub

Public ReadOnly Property PeriodMin() As UInt32
Get
Return m_uPeriodMin
End Get
End Property

Public ReadOnly Property PeriodMax() As UInt32
Get
Return m_uPeriodMax
End Get
End Property

End Structure

<DllImport("winmm.dll", SetLastError:=True)> _
Private Shared Function timeSetEvent( _
ByVal uDelay As UInt32, _
ByVal uResolution As UInt32, _
ByVal lpTimeProc As LPTIMECALLBACK, _
ByRef dwUser As Int32, _
ByVal fuEvent As EVENTFLAG) As UInt32
'
End Function

<DllImport("winmm.dll", SetLastError:=True)> _
Private Shared Function timeKillEvent( _
ByVal uTimerID As UInt32) As UInt32
'
End Function

<DllImport("winmm.dll", SetLastError:=True)> _
Private Shared Function timeGetDevCaps(ByRef lpTimeCaps As TIMECAPS,
ByVal uSize As UInt32) As UInt32
'
End Function

#End Region

#Region " Membres partagés "

Shared Sub New()

' Retrouve les résolutions (min et max)
' supportées par le timer système
timeGetDevCaps(m_tc, Convert.ToUInt32(Marshal.SizeOf(m_tc)))

Dim nErr As Int32 = Marshal.GetLastWin32Error()
If (nErr <> 0) Then
Throw New Win32Exception(nErr)
End If

End Sub

Public Shared ReadOnly Property MinimumResolution() As UInt32
Get
Return m_tc.PeriodMin
End Get
End Property

Public Shared ReadOnly Property MaximumResolution() As UInt32
Get
Return m_tc.PeriodMax
End Get
End Property

#End Region

Public Sub New()
End Sub

Public Sub New(ByVal uDelay As UInt32, _
ByVal uResolution As UInt32)
m_uDelay = uDelay
m_uResolution = uResolution
End Sub

Public Sub New(ByVal dwDelay As Int32, _
ByVal dwResolution As Int32)
m_uDelay = Convert.ToUInt32(dwDelay)
m_uResolution = Convert.ToUInt32(dwResolution)
End Sub

Public ReadOnly Property Delay() As UInt32
Get
Return m_uDelay
End Get
End Property

Public ReadOnly Property Resolution() As UInt32
Get
Return m_uResolution
End Get
End Property

Public Sub Start()

m_uTimerID = timeSetEvent(m_uDelay, _
m_uResolution, _
AddressOf TimeProc, _
0, _
EVENTFLAG.TIME_PERIODIC Or
EVENTFLAG.TIME_KILL_SYNCHRONOUS)

Dim nErr As Int32 = Marshal.GetLastWin32Error()
If (nErr <> 0) Then
m_uTimerID = Convert.ToUInt32(0)
Throw New Win32Exception(nErr)
End If

End Sub

Public Sub [Stop]()
timeKillEvent(m_uTimerID)
End Sub

Public Sub Dispose() Implements System.IDisposable.Dispose
[Stop]()
End Sub

Private Sub TimeProc(ByVal uID As UInt32, ByVal uMsg As UInt32, ByVal
dwUser As Int32, ByVal dw1 As Int32, ByVal dw2 As Int32)
RaiseEvent Callback(Me, New EventArgs)
End Sub

Protected Overrides Sub Finalize()
MyBase.Finalize()
Dispose()
End Sub

End Class
'***
' Form1
Public Class Form1
Inherits System.Windows.Forms.Form

Private m_timer As Timer

' code généré par le concepteur de form

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Me.Text = ""

' déclare un timer de 500 ms
m_timer = New Timer(500, 1)
AddHandler m_timer.Callback, AddressOf m_timer_Callback
m_timer.Start()

End Sub

Private Sub m_timer_Callback(ByVal sender As Object, ByVal e As
System.EventArgs)

Me.Text &= "."
If (Me.Text.Length = 10) Then
m_timer.Stop()
End If

End Sub

End Class
'***

--
Cordialement
Yanick
MVP pour Visual Basic