0

Есть функция. Туда я бросаю список List<double>, прохожусь по каждому элементу и рассчитываю некоторыми функциями новый массив. Так вот, каждую минуту поступает новый элемент в мой список и необходимо получить новый элемент в новом массиве. Получается, я буду каждый раз рассчитывать заного весь массив, чтобы получить конечный результат, т.к. там предыдущий расчет влияет на следующее значение. Есть ли как-нибудь способ, рассчитать, ждать, пока получу новый элемент, и просто продолжить цикл for уже с новый элементом?

Fresto
  • 1,158
  • Заведите вместо List ObservableCollection и подпишитесь на ее событие CollectionChanged – Андрей NOP Mar 06 '18 at 08:46
  • @АндрейNOP Да нет, это я знаю, но тут суть в том, что у меня цикл прохода по каждому элементу, чтобы получить результат. И соответственно, если я получу новый элемент, я должен рассчитать все предыдущие, чтобы дойти до него. А можно как-то рассчитать предыдущие и просто с каждым новым элементом цикл продолжал считать уже на основе предыдущих вычислений. Звучит странно, но может есть что-то для этого) – Fresto Mar 06 '18 at 08:53
  • Просто храните последнее рассчитанное значение. Или список рассчитанных значений. – Alexander Petrov Mar 06 '18 at 09:13
  • Вообще-то там возвращается информация об индексе и элементе, подвергшемся изменениям: https://msdn.microsoft.com/ru-ru/library/system.collections.specialized.notifycollectionchangedeventargs(v=vs.110).aspx – Андрей NOP Mar 06 '18 at 09:24
  • @АндрейNOP Я вас понял, я это событие уже использовал, просто для другого. А тут вопрос немного в другом был) – Fresto Mar 06 '18 at 09:29
  • Я вас не понимаю, ну используйте еще раз для этого уже... ObservableCollection вам сообщит какой конкретно элемент изменился и перебирать все предыдущие смысла нету – Андрей NOP Mar 06 '18 at 09:33
  • @АндрейNOP суть в том, что функции расчета очень большие и их слишком много, чтобы в них разобраться. Но по сути у меня есть просто цикл и в нем вся эта каша. Поэтому я и хотел узнать, можно ли, если for дойдет до последнего элемента, он остановился и ждал, когда в массив добавят еще один элемент и он продолжил свой цикл. И так до бесконечности. – Fresto Mar 06 '18 at 09:40
  • @Fresto, ага, я понял вас. Ну тогда вам нужен не List, а IEnumerable и перебирать его через foreach. Попробую набросать пример... – Андрей NOP Mar 06 '18 at 09:42
  • @АндрейNOP спасибо большое, если даже с примером выложите!) – Fresto Mar 06 '18 at 09:49

1 Answers1

3

Ваша задача похожа на паттерн producer/consumer. Один участок кода производит данные, другой - потребляет их.

В современном C# очень удобно использовать конвейеры (pipelines).

Упрощённый пример, как это может выглядеть в вашем случае:

class Program
{
    static void Main(string[] args)
    {
        var inputValues = new BlockingCollection<double>();

        var getValues = Task.Run(() =>
        {
            try
            {
                var rnd = new Random();
                for (int i = 0; i < 10; i++)
                {
                    inputValues.Add(rnd.NextDouble());
                    Thread.Sleep(1000);
                }
            }
            finally { inputValues.CompleteAdding(); }
        });

        var processValues = Task.Run(() =>
        {
            foreach (var value in inputValues.GetConsumingEnumerable())
            {
                ProcessValue(value);
            }
        });

        Task.WaitAll(getValues, processValues);
    }

    static void ProcessValue(double value)
    {
        var result = value * 100;
        Console.WriteLine(result);
    }
}

В данном консольном приложении один поток помещает данные в BlockingCollection, другой считывает их по мере поступления и выполняет обработку. Благодаря вызову метода GetConsumingEnumerable второй поток будет сколь угодно долго ждать появления новых данных. До тех пор, пока первый поток не вызовет метод CompleteAdding.

  • 1
    Да лааадно, как всё просто оказывается, а я тут разбираюсь в каждой функции, пытаюсь сделать так, чтобы расчет проводился конкретно по 1 элементу, выбираю, сколько нужно элементов в массиве иметь, чтобы получить результат. А в итоге вот так всё просто может быть) Огромное спасибо вам за помощь, это слишком упростит мою работу!) – Fresto Mar 06 '18 at 10:18