Интервал таймера Переполнение визуального базового

я пытаюсь использовать Timer, это работает хорошо, я использую его с другими переменными

 Const daily As Integer = 86400000
 Const weekly As Integer = 604800000
 Const hour As Integer = 3600000

но я получаю ошибку переполнения при использовании ежемесячной переменной Private monthly As Long вот мой код

Private timepick As New DateTimePicker()
Private timeLeft As Long
Public trackTimer As Long
Private CloseAllowed As Boolean
Private time As ULong
Private progress As Long
Const daily As Integer = 86400000
Const weekly As Integer = 604800000
Const hour As Integer = 3600000
Private monthly As Long
Private currentDate As Date = DateTime.Now
Private controller As Boolean = False

Private Sub AutoShutDown_Tick(sender As Object, e As EventArgs) Handles AutoShutDown.Tick
    If (controller = False) Then
        AutoShutDown.Enabled = False
    Else
        CountDown.Enabled = True
        progress = 0
        WarningForm.Timer1.Enabled = True
        timeLeft = time
        trackTimer = timeLeft
        AutoShutDown.Interval = time 'Overflow 
        ProgressBar1.Maximum = timeLeft
    End If
    'System.Diagnostics.Process.Start("shutdown", "-s -t 00")
    MsgBox("Shuting down...")
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    timepick.Format = DateTimePickerFormat.Time
    timepick.ShowUpDown = True
    timepick.Location = New Point(154, 12)
    timepick.Width = 123
    Me.Controls.Add(timepick)
    cmbAction.SelectedIndex = 0
    rdoOnce.Checked = True
    Dim days As Long = DateTime.DaysInMonth(currentDate.Year, currentDate.Month)
    monthly = (days * daily)
End Sub

часть моего Select Case

   Case "Monthly"
            Dim dueDate As Date = DateTime.Parse(currentDate.Month & "/" & cmbControl.Text & "/" & currentDate.Year & " " & timepick.Text)
            Dim dayOfTheMonth As Integer = ((dueDate.Day * 24 - currentDate.Hour) * hour) + (dueDate.Minute * 60000) + (dueDate.Hour * hour)
            Dim currentDayOfTheMon As Integer = ((currentDate.Day * 24 - currentDate.Hour) * hour) + (currentDate.Minute * 60000) + (currentDate.Hour * hour)
            If (dayOfTheMonth > currentDayOfTheMon) Then
                timeLeft = (dayOfTheMonth - currentDayOfTheMon)
            End If
            time = monthly
            controller = True
    End Select

    trackTimer = timeLeft
    ProgressBar1.Maximum = timeLeft
    AutoShutDown.Interval = timeLeft
    AutoShutDown.Enabled = True
    CountDown.Enabled = True

person Junius L.    schedule 22.12.2014    source источник


Ответы (1)


но я получаю ошибку переполнения при использовании ежемесячной переменной

Это хорошая проблема, она говорит вам, что ваш код плохой. Свойство Timer Interval является целым числом, единицей измерения являются миллисекунды. Один месяц равен 31 х 24 х 3600 х 1000 = 2 678 400 000 миллисекунд. Это больше, чем Integer.MaxValue, 2 147 483 648. Или, другими словами, вы не можете использовать Timer для измерения времени более чем на 24 дня, используя миллисекунды.

Простой обходной путь — не отсчитывать весь период, а позволить таймеру тикать, скажем, каждый час. Фактический интервал не имеет значения, просто проверьте, достаточно ли времени прошло. Грубо:

Private ShutdownDate As DateTime

Private Sub StartShutdownTimer(ByVal interval As Long)
    ShutdownDate = DateTime.UtcNow.AddMilliseconds(interval)
    AutoShutDown.Enabled = True
End Sub

Private Sub AutoShutDown_Tick(sender As Object, e As EventArgs)
    If DateTime.UtcNow >= ShutdownDate Then
        AutoShutDown.Enabled = False
        '' etc...
    End If
End Sub
person Hans Passant    schedule 22.12.2014