#c# #.net
#c# #.net
Вопрос:
У меня есть приведенный ниже код, который отлично работает для меня. Для демонстрационных целей я добавляю в список только несколько записей в режиме реального времени, этот список постоянно пополняется новыми значениями в секунду. вопрос в том, как сортировать эти данные в реальном времени на основе временного интервала? Размещенный ниже код в постоянно работающем webjob.
public class MyObject
{
public double Value { get; set; }
public DateTime Time { get; set; }
public DateTime GetStartOfPeriodByMins(int numMinutes)
{
int oldMinutes = Time.Minute;
int newMinutes = (oldMinutes / numMinutes) * numMinutes;
DateTime startOfPeriod = new DateTime(Time.Year, Time.Month, Time.Day, Time.Hour, newMinutes, 0);
return startOfPeriod;
}
}
List<MyObject> inputList = new List<MyObject>();
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 0), Value = 12});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 2), Value = 11});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 5), Value = 13});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 15), Value = 14});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 45), Value = 12});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 55), Value = 11});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 16, 0), Value = 13});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 16, 1), Value = 16});
var resultSet = inputList
.GroupBy(i => i.GetStartOfPeriodByMins(1))
.Select(gr =>
new
{
StartOfPeriod = gr.Key,
Min = gr.Min(item => item.Value),
Max = gr.Max(item => item.Value),
Open = gr.OrderBy(item => item.Time).First().Value,
Close = gr.OrderBy(item => item.Time).Last().Value
});
var my = resultSet.ToList();
Временной интервал, взятый здесь, составляет 1 минуту, поэтому для каждой минуты он будет давать мне отдельные значения для открытия, максимума, минимума и закрытия этих минут.
Я хочу обрабатывать данные inputList
так, чтобы через каждые 1 минуту я получал последний набор данных за последние 1 минуту, чтобы я мог использовать его для дальнейших вычислений.
Комментарии:
1. кто пометил его закрытым, не указав никаких входных данных: ( попробуйте дать какой-нибудь фрагмент кода, который я могу попробовать. Эти типы вопросов очень сложны и полезны для многих пользователей.
2. Я бы предположил, что кто-то пометил это для закрытия, поскольку неясно, о чем вы здесь спрашиваете. Что именно означает, что «InputList будет получать непрерывные новые данные из API»?
3. О, хорошо, я разместил этот код в azure webjob, поэтому api — это websocket api, который постоянно выдает мне данные о тике, которые я добавляю в inputlist… Пожалуйста, укажите, как это отсортировать
Ответ №1:
Поскольку он продолжает вставки (add), вы можете использовать SortedSet вместо этого в списке.
public class MyObjectComparer : IComparer<MyObject>
{
public int Compare(MyObject x, MyObject y)
{
return x.Time.CompareTo(y.Time);
}
}
var inputList = new SortedSet<MyObject>(new MyObjectComparer());
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 0), Value = 12});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 2), Value = 11});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 5), Value = 13});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 15), Value = 14});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 45), Value = 12});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 15, 55), Value = 11});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 16, 0), Value = 13});
Thread.Sleep(1000);
inputList.Add(new MyObject() {Time = new DateTime(2020, 10, 10, 9, 16, 1), Value = 16});
Таким образом, для каждого добавления набор (список) будет в правильном порядке.
public class MyObject
{
public double Value { get; set; }
public DateTime Time { get; set; }
public DateTime Created { get; } = DateTime.Now;
public DateTime Ttl { get; } = DateTime.Now.AddMinues(5);
public DateTime? Persisted { get; set; }
public bool IsDead => DateTime.Now > Ttl;
public bool IsPersisted => Persisted.HasValue;
public bool TimeToPersist => IsPersisted == false amp;amp; DateTime.Now > Create.AddMinutes(2);
public DateTime GetStartOfPeriodByMins(int numMinutes)
{
int oldMinutes = Time.Minute;
int newMinutes = (oldMinutes / numMinutes) * numMinutes;
DateTime startOfPeriod = new DateTime(Time.Year, Time.Month, Time.Day, Time.Hour, newMinutes, 0);
return startOfPeriod;
}
}
Комментарии:
1. Большое спасибо… есть ли какой-либо способ сохранить данные только текущих 1 минут или 5 минут в новом списке, и через 1 или 5 минут он очистит старые данные?
2. нет, для этого у вас есть собственное состояние Persisted и TTL (время жизни).
3. Хорошо, я думаю, мне нужно создать новый список, в котором я могу сохранять последние данные за 1 минуту или 5 минут из Inputlist. Правильно? Любой пример фрагмента кода, который вы можете придумать, я также попробую с моей стороны, например, использовать MemoryCache спасибо
4. Я обновил ответ некоторыми свойствами
MyObject
, которые должны поддерживать ваш запрос. Просто укажите минуты….5. Вы должны запустить список «вручную» и удалить их, то
IsDead == true
же самое касается тех, которые должны быть сохранены.