Question Generate an event after a time period

nicorvp

Member
Joined
May 3, 2009
Messages
24
Location
Italy
Programming Experience
5-10
Hi, I need to take a shot from a camera every last day of the month at midnight. I know how to to take the shot, but I don't know how to generate an event repetitively after a time period. I thought about to calculate the time between now and the next shot time, but how to run a method after a time period?
Thanks
 
Once you've calculated the time period, convert that to milliseconds and assign it to the Interval of a Timer. Start the Timer and it will raise its Tick event after that time period.

Note that Interval is type Integer so its maximum value is Int32.MaxValue, which corresponds to about 24 days. If that's not enough for you then I'd suggest having the Timer Tick every day at the appropriate time. When it Ticks you can check the date and either do the job or let the Timer continue.
 
Haven't tested it or anything... but here's a class I slapped together just now. You can create an instance and set it to populate an event every so often by some interval:

Single -> only once in the future, pass it a Date object for when
Daily -> at a specific time in the day
Weekly -> at a specific time in the week
Interval -> over some repeated interval, must pass a starting Date object, and then a timespan... it bursts every time the timespan passes from the start Date

others can be added of course, to meet needs. This just kind of gives an idea of how I would have done it.

VB.NET:
Public Class TimeInterval

    Private Shared ReadOnly MILLISECONDS_TO_TICKS As Integer = 10000
    Private Shared ReadOnly MILLISECONDS_IN_DAY As Integer = 864000000
    Private Shared ReadOnly MILLISECONDS_IN_WEEK As Integer = 604800000

#Region "Events, internal types and structures"
    Public Enum TimeIntervalType
        [Single] = 0
        Daily = 1
        Weekly = 2
        Interval = 3
    End Enum

    Public Event TimeIntervalPassed As EventHandler

    Protected Sub OnTimeIntervalPassed(ByVal e As EventArgs)
        RaiseEvent TimeIntervalPassed(Me, e)
    End Sub

#End Region

#Region "Fields"
    Private _type As TimeIntervalType
    Private _lastDate As Date
    Private _span As TimeSpan

    Private WithEvents _timer As New System.Timers.Timer()
#End Region

#Region "CONSTRUCTOR"
    Public Sub New()

    End Sub


#End Region

#Region "Properties"
    Public ReadOnly Property IntervalType() As TimeIntervalType
        Get
            Return _type
        End Get
    End Property
#End Region


#Region "Public Configuration Methods"
    Public Sub SetAsSingle(ByVal dt As Date)
        _type = TimeIntervalType.Single
        _lastDate = dt
        _span = New TimeSpan(0)

        Me.StartUpTimer()
    End Sub

#Region "SetAsDaily(...) overloads"
    Public Sub SetAsDaily(ByVal milliseconds As Integer)
        _type = TimeIntervalType.Daily
        _lastDate = Nothing
        _span = New TimeSpan(Math.Max(0, Math.Min(MILLISECONDS_IN_DAY, milliseconds)) * MILLISECONDS_TO_TICKS) ''864000000 == milliseconds in a day

        Me.StartUpTimer()
    End Sub

    Public Sub SetAsDaily(ByVal seconds As Integer, ByVal milliseconds As Integer)
        SetAsDaily((seconds * 1000) + milliseconds)
    End Sub

    Public Sub SetAsDaily(ByVal minutes As Integer, ByVal seconds As Integer, ByVal milliseconds As Integer)
        SetAsDaily((minutes * 60 * 1000) + (seconds * 1000) + milliseconds)
    End Sub

    Public Sub SetAsDaily(ByVal hours As Integer, ByVal minutes As Integer, ByVal seconds As Integer, ByVal milliseconds As Integer)
        SetAsDaily((hours * 60 * 60 * 1000) + (minutes * 60 * 1000) + (seconds * 1000) + milliseconds)
    End Sub

    Public Sub SetAsDaily(ByVal span As TimeSpan)
        SetAsDaily(span.Milliseconds)
    End Sub
#End Region


#Region "SetAsWeekly(...) overloads"
    Public Sub SetAsWeekly(ByVal milliseconds As Integer)
        _type = TimeIntervalType.Weekly
        _lastDate = Nothing
        _span = New TimeSpan(Math.Max(0, Math.Min(MILLISECONDS_IN_WEEK, milliseconds)) * MILLISECONDS_TO_TICKS) ''604800000 == milliseconds in a week

        Me.StartUpTimer()
    End Sub

    Public Sub SetAsWeekly(ByVal seconds As Integer, ByVal milliseconds As Integer)
        SetAsWeekly((seconds * 1000) + milliseconds)
    End Sub

    Public Sub SetAsWeekly(ByVal minutes As Integer, ByVal seconds As Integer, ByVal milliseconds As Integer)
        SetAsWeekly((minutes * 60 * 1000) + (seconds * 1000) + milliseconds)
    End Sub

    Public Sub SetAsWeekly(ByVal hours As Integer, ByVal minutes As Integer, ByVal seconds As Integer, ByVal milliseconds As Integer)
        SetAsWeekly((hours * 60 * 60 * 1000) + (minutes * 60 * 1000) + (seconds * 1000) + milliseconds)
    End Sub

    Public Sub SetAsWeekly(ByVal days As Integer, ByVal hours As Integer, ByVal minutes As Integer, ByVal seconds As Integer, ByVal milliseconds As Integer)
        SetAsWeekly((days * 24 * 60 * 60 * 1000) + (hours * 60 * 60 * 1000) + (minutes * 60 * 1000) + (seconds * 1000) + milliseconds)
    End Sub

    Public Sub SetAsWeekly(ByVal span As TimeSpan)
        SetAsWeekly(span.Milliseconds)
    End Sub

#End Region

    Public Sub SetAsInterval(ByVal start As Date, ByVal span As TimeSpan)
        _type = TimeIntervalType.Interval
        _lastDate = start
        _span = span

        Me.StartUpTimer()
    End Sub
#End Region


    Public Function GetNextPosition() As Date

        Select Case _type
            Case TimeIntervalType.Single
                Return _lastDate

            Case TimeIntervalType.Daily
                Dim now As Date = Date.Now
                _lastDate = New Date(now.Year, now.Month, now.Day)
                _lastDate.AddTicks(_span.Ticks)

                If _lastDate.Ticks < Date.Now.Ticks Then _lastDate.AddDays(1)

                Return _lastDate

            Case TimeIntervalType.Weekly
                Dim now As Date = Date.Now
                now.AddDays(-now.DayOfWeek)
                _lastDate = New Date(now.Year, now.Month, now.Day)
                _lastDate.AddTicks(_span.Ticks)

                If _lastDate.Ticks < Date.Now.Ticks Then _lastDate.AddDays(1)

                Return _lastDate

            Case TimeIntervalType.Interval
                While _lastDate.Ticks < Date.Now.Ticks
                    _lastDate.AddTicks(_span.Ticks)
                End While

                Return _lastDate

        End Select

    End Function




#Region "Private Timer/Event Burst"
    Private _bShortChange As Boolean

    Private Sub StartUpTimer()
        Dim dt As Date = Me.GetNextPosition()
        Dim span As TimeSpan = dt - Date.Now
        Dim milli As Long = span.Ticks / MILLISECONDS_TO_TICKS

        If milli < 0 Then Exit Sub


        _bShortChange = (milli > MILLISECONDS_IN_DAY)
        If _bShortChange Then milli = MILLISECONDS_IN_DAY

        _timer.Interval = milli
        _timer.Start()

    End Sub

    Private Sub Timer_Elapsed(ByVal sender As Object, ByVal e As EventArgs) Handles _timer.Elapsed

        If Not _bShortChange Then
            OnTimeIntervalPassed(New EventArgs())

        End If

        Me.StartUpTimer()

    End Sub
#End Region
End Class
 
Back
Top