Получить среднее значение в секунду. Как это сделать более правильно? Здравствуйте. Мне нужно рассчитать среднее значение полученных данных в секунду.
Например, есть класс:class StateMonitor
{
private long _quantityOfValues;
private long _quantityOfCalls;
private readonly object _quantityOfValuesSync = new object();
private readonly object _frequencySync = new object();
public void Increment()
{
lock (_quantityOfValuesSync)
{
++_quantityOfValues;
}
}
public int Frequency
{
get
{
long quantityOfValues;
lock (_quantityOfValuesSync)
{
quantityOfValues = _quantityOfValues;
}
lock (_frequencySync)
{
double result = (double)quantityOfValues / ++_quantityOfCalls;
result = Math.Round(result, MidpointRounding.AwayFromZero);
return (int)result;
}
}
}
}
Чтобы он правильно считал частоту вызова метода Increment в секунду нужно вызывать свойство Frequency 1 раз в секунду. Что нельзя назвать удобным и надёжным. Наверняка есть формула для такого подсчёта. Догадываюсь, что нужно будет сохранять время последнего вызова свойства Frequency, чтобы правильно считать. Чёт никак не допетрю, как же правильно считать?
Вот код для теста класса выше:using System;
using System.Threading;
using System.Threading.Tasks;
namespace FrequencyReceivingTest2
{
internal class Program
{
#region Entry point
private static Program _program;
private static void Main(string[] args)
{
_program = new Program();
_program.Run(args);
}
#endregion
private void Run(string[] args)
{
var monitor = new StateMonitor();
int counter = 0;
Task[] tasks =
{
new Task(() => {
while (counter++
{
while (counter task.Start());
Task.WaitAll(tasks);
Console.WriteLine("Конец.");
Console.ReadKey();
}
}
}

21 Авг 2019 в 06:09
196 +1
0
Ответы
1

Для более надежного и удобного подсчета среднего значения в секунду можно внести некоторые изменения в класс StateMonitor.

Одним из способов сделать это является добавление поля для сохранения времени последнего вызова метода Increment и изменение метода Frequency для учета временного интервала между вызовами.

Вот пример модифицированного класса StateMonitor:

class StateMonitor
{
private long _quantityOfValues;
private long _quantityOfCalls;
private DateTime _lastUpdate;
private readonly object _quantityOfValuesSync = new object();
private readonly object _frequencySync = new object();
public void Increment()
{
lock (_quantityOfValuesSync)
{
++_quantityOfValues;
}
}
public int Frequency
{
get
{
DateTime now = DateTime.Now;
lock (_quantityOfValuesSync)
{
double timeElapsed = (now - _lastUpdate).TotalSeconds;
if (timeElapsed > 0)
{
double result = (double)_quantityOfValues / timeElapsed;
return (int)Math.Round(result, MidpointRounding.AwayFromZero);
}
else
{
return 0;
}
}
}
}
public void UpdateLastUpdate()
{
_lastUpdate = DateTime.Now;
++_quantityOfCalls;
}
}

В методе Increment можно добавить вызов метода UpdateLastUpdate для обновления времени последнего вызова. А метод Frequency теперь учитывает временной интервал между вызовами, что позволит более точно рассчитать среднее значение в секунду.

Теперь в методе Main можно вызывать UpdateLastUpdate после каждого вызова Increment:

new Task(() =>
{
while (counter++ < 20)
{
int ms = 0;
while (ms < 1000)
{
const int WaitMs = 200;
monitor.Increment();
monitor.UpdateLastUpdate();
Thread.Sleep(WaitMs);
ms += WaitMs;
}
}
}),

Эти изменения позволят более надежно и удобно рассчитывать среднее значение в секунду на основе полученных данных.

20 Апр в 13:22
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 91 905 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир