none
Ошибка очередности RRS feed

  • Общие обсуждения

  • Здравствуйте.
    Помогите, пожалуйста, найти ошибку в коде. Уже всю голову сломал.
    С сервера приходят данные (symbol, datetime, val1), добавляются в буфер (очередь):

    private void SmartServer_AddTick(string symbol, System.DateTime datetime, double val1)
            {
                lock (TicksBuffer)
                {
                    TicksBuffer.Enqueue(new BufferedTick(symbol, datetime, val1));
     
                    // Очередь уже не пуста
                    if (TicksBuffer.Count == 1)
                        Monitor.PulseAll(TicksBuffer); // Оповестить все ожидающие потоки о том, что в очереди появились элементы.
                }
            }
    Затем обрабатываются в отдельном потоке:
    private void ScanTicks()
            {
                while (!this.IsDisposed)
                {
                    // Вход в критическую зону
                    lock (TicksBuffer)
                    {
                        while (TicksBuffer.Count == 0)
                            Monitor.Wait(TicksBuffer); // Очередь пуста - размыкание объекта для других потоков и ожидание появления новых элементов.
                        tempTick = TicksBuffer.Dequeue();
                    }
                    switch (tempTick.Symbol)
                    {
                        case "AEKC":
                                makeSec();
                            break;
     
                        case "BCKC":
                                makeSec();
                            break;
                    }
                }
            }
    Метод makeSec добавляет каждый тик в список секундных значений Sec:
    private void makeSec()
            {
                // Если появилась первая строчка
                if (!firstTickCome)
                {
                    prevDate = tempTick.Time;
                    Sec.Add(new Tick(tempTick.Time, tempTick.Val1));
                    firstTickCome = true;
                }
                else
                {
                    // Появилась вторая строчка или последующие строчки
                    // Если время текущей строчки равно времени предыдущей
                    if (tempTick.Time == prevDate)
                    {
                        Sec[Sec.Count - 1] = new Tick(tempTick.Time, tempTick.Val1);
                    }
                    else
                    {
                        // Если время текущей строчки НЕ равно времени предыдущей
                        TimeSpan dif = tempTick.Time - prevDate;
                        difInSecs = (int)dif.TotalSeconds;
                        // Если время текущей строчки отличается от времени предыдущей строчки на 1 секунду
                        if (difInSecs == 1)
                        {
                            Sec.Add(new Tick(tempTick.Time, tempTick.Val1));
                            prevDate = tempTick.Time;
                        }
                        else
                        {
                            // Если время текущей строчки отличается от времени предыдущей строчки более чем на 1 секунду
                            for (int i = difInSecs; i > 1; i--)
                            {
                                Sec.Add(new Tick(tempTick.Time.AddSeconds(1 - i), 0));
                            }
     
                            Sec.Add(new Tick(tempTick.Time, tempTick.Val1));
                            prevDate = tempTick.Time;
                        }
                    }
                }
            }

    В результате получается вот такой список Sec:
    24.10.2011 18:36:01, 151,71500270084
    24.10.2011 18:36:02, 151,65856443362
    24.10.2011 18:36:03, 151,66224750684
    24.10.2011 18:36:04, 151,64387533096
    24.10.2011 18:36:05, 151,6254943375
    24.10.2011 18:36:06, 151,72191281895
    24.10.2011 18:36:07, 151,81560564559
    24.10.2011 18:36:08, 151,8332489681
    24.10.2011 18:36:09, 151,87534100697
    24.10.2011 18:36:10, 151,87474647154
    24.10.2011 18:36:11, 151,74139895135
    24.10.2011 18:36:12, 151,74139895135
    24.10.2011 18:36:11, 151,74139895135
    24.10.2011 18:36:12, 151,71271097189
    24.10.2011 18:36:13, 151,72242065422

    Сначала секунды идут по порядку как и должны, но потом почему-то все сбивается и секунды начинают чередоваться. Почему время сбивается ума не приложу.

    24 октября 2011 г. 15:10

Все ответы

  • Здравствуйте.

    Сколько потоков ожидают данные и сколько обрабатывают? Если просто сохранить данные в список, то перемешки секунд наблюдаться не будет?

     

     


    Для связи [mail]
    25 октября 2011 г. 9:16
  • давайте уточним. есть метод, который принимает какие-то данные. принимать он их должен максимально быстро. поэтому метод ставит данные в очередь на обработку. обработкой данных занимается отдельный поток.
    если в течении секунды данные поступали несколько раз, то сохраняется только последнее поступление. но если данные не поступали в течение нескольких секунд, минут и т.д., то для каждой секунды надо сохранить значение по-умолчанию. правильно? вроде была такая тема.

    25 октября 2011 г. 15:09
  • Обработка события SmartServer_AddTick выполняется в основном потоке. В одном дополнительном потоке запущен метод ScanTicks

    Thread ThreadScanTicks = new Thread(new ThreadStart(ScanTicks));
    ThreadScanTicks.IsBackground = true;
    ThreadScanTicks.Start();

    Других потоков, относящихся к ScanTicks и TicksBuffer нет. В каждую конкретную секунду приходит несколько сотен строк, относящихся к этой секунде. Т.е. если сохранить данные в список получится несколько сотен строк с одинаковым временем, например 24.10.2011 18:36:13, затем несколько сотен строк с временем 24.10.2011 18:36:14. Сколько просматривал мне не попадались нарушения последовательности секунд, но теоретически, думаю возможно, что пакет, отправленный с сервера первым придет после пакета, отправленного вслед за ним из-за раундтрипа до сервера.

    25 октября 2011 г. 16:38
  • то для каждой секунды надо

    значение Val1 заменить на 0.

    Тема была как сделать тоже самое без списка. Я это сделал. Теперь вопрос в другом.

    25 октября 2011 г. 16:43