Tommy Jo Ответов: 1

Как получить среднее значение непрерывного обновления значения каждые одну секунду


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

Что я уже пробовал:

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
   'Timer1 with intervel 1000ms    
    Dim OneSecPulse As Boolean
    Dim Data As Double
    Dim Total As Double
    Dim Average As Double
    Dim Counts As Integer

    OneSecPulse = True
    
    If OneSecPulse = True Then
        Counts = Counts + 1
        Total = Total + Data
        OneSecPulse = False
    End If

    If Counts = 60 Then
        Average = Total / 60
        Total = 0
        Counts = 0
    End If

End Sub

ZurdoDev

Сложите их и затем разделите. В чем проблема?

F-ES Sitecore

Все ваши переменные локальны для события tick, поэтому каждый раз, когда оно срабатывает, инициализируйте его до 0. Вам нужно переместить объявление переменных count и total на уровень класса, чтобы их значения сохранялись вне события.

1 Ответов

Рейтинг:
8

Richard Deeming

Значения локальных переменных не сохраняются между вызовами метода. Каждый раз, когда ваш Timer1_Tick при вызове метода все локальные переменные будут установлены по умолчанию.

У вас также нет никакого кода для извлечения данных - вы просто добавляете 0 к общей сумме каждый раз.

Вам нужно сохранить список значений в поле. Каждый раз, когда вы добавляете новое значение, удалите все слишком старые значения, прежде чем вычислять среднее значение.

Простой класс для хранения значений может выглядеть примерно так:

Imports System
Imports System.Collections.Generic
Imports System.Linq

Public Class RollingAverage
    Private ReadOnly _limit As Integer
    Private _values As Queue(Of Double)
    
    Public Sub New(ByVal limit As Integer)
        _limit = limit
        _values = New Queue(Of Double)
    End Sub
    
    Public Sub Add(ByVal value As Double)
        If _values.Count = _limit Then
            _values.Dequeue()
        End If
        
        _values.Enqueue(value)
    End Sub
    
    Public ReadOnly Property Count As Integer
        Get
            Return _values.Count
        End Get
    End Property
    
    Public ReadOnly Property Average As Double
        Get
            Return _values.Average()
        End Get
    End Property
End Class
Сохраните экземпляр этого класса в поле и используйте его для вычисления средних значений:
Private _averages As New RollingAverage(60)

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    
    Dim data As Double = ... TODO: Get the data from somewhere ...
    
    _averages.Add(data)
    
    If _averages.Count = 60 Then
        Average = _averages.Average
    End If
End Sub


Maciej Los

Превосходно!