Вы задаете несколько разных вопросов здесь. Все связаны. Ваши требования не очень подробны, но я думаю, что могу указать вам правильное направление. Я собираюсь предположить, что все, что вам нужно, это количество событий в секунду, в течение некоторого периода в прошлом. Таким образом, все, что нам нужно, это какой-то способ хранить целое число (количество событий) каждую секунду в течение этого периода.
86 400 секунд в день. Допустим, вы хотите получить информацию за 10 дней. Вы можете создать кольцевой буфер размером 864 000 для хранения счетчиков за 10 дней:
const int SecondsPerDay = 86400;
const int TenDays = 10 * SecondsPerDay;
int[] TenDaysEvents = new int[TenDays];
То есть у вас всегда есть последние 10 дней.
Предполагая, что у вас есть обработчик событий, который читает данные вашего сокета и передает информацию в функцию, вы можете легко обновлять свои данные:
DateTime lastEventTime = DateTime.MinValue;
int lastTimeIndex = 0;
void ProcessReceivedEvent(string event)
{
// here, parse the event string to get the DateTime
DateTime eventTime = GetEventDate(event);
if (lastEventTime == DateTime.MinValue)
{
lastTimeIndex = 0;
}
else if (eventTime != lastEventTime)
{
// get number of seconds since last event
var elapsedTime = eventTime - lastEventTime;
var elapsedSeconds = (int)elapsedTime.TotalSeconds;
// For each of those seconds, set the number of events to 0
for (int i = 1; i <= elapsedSeconds; ++i)
{
lastTimeIndex = (lastTimeIndex + 1) % TenDays; // wrap around if we get past the end
TenDaysEvents[lastTimeIndex] = 0;
}
}
// Now increment the count for the current time index
++TenDaysEvents[lastTimeIndex];
}
Это сохраняет в памяти последние 10 дней и легко обновляется. Отчетность немного сложнее, потому что начало может быть в середине массива. То есть, если текущий индекс равен 469301, то время запуска составляет 469302. Это кольцевой буфер. Наивным способом сообщить об этом будет скопировать циклический буфер в другой массив или список с начальной точкой в позиции 0 в новой коллекции, а затем сообщить об этом. Или вы можете написать собственный перечислитель, который отсчитывает от текущей позиции и начинает там. Это не было бы особенно сложно создать.
Прелесть вышеописанного в том, что ваш массив остается статичным. Вы выделяете его один раз и просто используете повторно. Возможно, вы захотите добавить еще 60 записей, чтобы между текущим временем и временем 10 дней назад был некоторый «буфер». Это предотвратит изменение данных за 10 дней назад во время запроса. Добавьте еще 300 предметов, чтобы получить 5-минутный буфер.
Другой вариант - создать связанный список записей. Опять один раз в секунду. При этом вы добавляете элементы в конец списка и удаляете более старые элементы спереди. Всякий раз, когда событие приходит в течение новой секунды, добавьте запись о событии в конец списка, а затем удалите записи, которые находятся более чем на 10 дней (или независимо от вашего порога), из начала списка. Вы все еще можете использовать LINQ, чтобы сообщать о вещах, как рекомендуется в другом ответе.
Вы тоже можете использовать гибрид. По мере прохождения каждой секунды записывайте запись в базу данных и сохраняйте в памяти последнюю минуту, или час, или что-то еще. Таким образом, у вас есть самые свежие данные, доступные в памяти для быстрых отчетов и обновлений в реальном времени, но вы также можете использовать базу данных для составления отчетов за любой период с момента первого сбора данных.
Что бы вы ни решили, вам, вероятно, следует иметь какую-то базу данных, потому что вы не можете гарантировать, что ваша система не выйдет из строя. Фактически, вы можете в значительной степени гарантировать, что ваша система выйдет из строя в какой-то момент. Потеря данных или необходимость сканировать терабайты данных журналов - это не весело, чтобы заново собрать данные, которые вы собрали с течением времени.