none
Переход от class к struct Ошибка: StackOverFlow(Продолжение) RRS feed

  • Вопрос

  • http://social.msdn.microsoft.com/Forums/ru-RU/f52bc32f-a581-4377-ab5b-0f1fc87059ac/-class-struct-stackoverflow

    В ходе опытного тыка получилось, что ошибка связана с операцией:

    (сам класс CircularBuffer<T> я поместил в ViewModelBase.cs)

    public T ElementAt(int index)
           {
               if ((index >= plainBuffer.Length) || (index < 0))
                   throw new IndexOutOfRangeException();
    
               index += _startIndex;
    
               if (index >= plainBuffer.Length)
                   index -= plainBuffer.Length;
    
               return plainBuffer[index];
           }

    В MainWindow был создан массив:

    MassivBar20tick = new CircularBuffer<BarType>(100);
    public struct BarType
        {
            public DateTime DateTimeOB { get; set; }
            public decimal OpenPrice { get; set; }
            public decimal MaxPrice { get; set; }
            public decimal MinPrice { get; set; }
            public decimal ClosePrice { get; set; }
    ...
    
    ...
    
    ..
    }

    Из файла Model одного из окон модели MVVM шло очень много операций вида:


    PriceLoc=MainWindow.MassivBar20tick.ElementAt(i).Price;

    Если у какой-то из циклических коллекций не слишком много обращений, то ошибка не возникает.У одного массива 4000 вызовов встречаются в коде, где-то циклы от 0 до 50 вызовов свойств из разных элементов коллекции.А т к функция с ошибкой находится на обработчике событий и вызывается очень часто в соответсвии с потоком биржевых данных, каждый тик данных, то в единицу времени операций доступа к массиву возникает очень много.

    По возможности стал создавать:

    TypeStruct Temp= NameStruct.ElementAt(0);

    С классами таких проблем нет, с чем это связано?И какой самый быстрый способ доступа к даннным моего циклического массива к отдельным свойствам элемента массива?И чтобы переполнения стэка не было при большом количестве операций. Каждый раз загружать целый элемент массива наверное плохо сказывается на производительности.


    Eugene







    22 августа 2013 г. 12:12

Все ответы

  • С классами говорите все идет быстрее? Может дело в том что всякий раз когда вы вызываете любое свойство, то происходит упаковывание. А если вместо свойств в структуре сделать просто поля? как тут:

     public DateTime DateTimeOB;
            public decimal OpenPrice;
            public decimal MaxPrice;
            public decimal MinPrice ;
            public decimal ClosePrice ;

    22 августа 2013 г. 12:57
  • А доступ к отдельным членам каждого элемента массива верный? Или может быть есть другие способы доступа? Там есть какие-то ограничения на единовременое количество обращений?




    Eugene





    22 августа 2013 г. 13:12
  • Там есть какие-то ограничения на единовременое количество обращений? - многопоточность?

    А как у вас реализован plainBuffer? Что за тип?

    • Изменено Higgs.Boson 23 августа 2013 г. 6:42 Дополнение
    23 августа 2013 г. 6:35
  • public   class CircularBuffer<T>
       {
          
           public CircularBuffer(int capacity)
           {
               plainBuffer = new T[capacity];
               _startIndex = 0;
           }
    
           private T[] plainBuffer;
           private int _startIndex; // Stores the start of the Circular Buffer
           private int _CountMember;// количество членов в коллекции сейчас Но не более Capacity
           private bool _FlagFull = false;
           int indexLoc = 0;
          
           public int Capacity
           {
               get { return plainBuffer.Length; }
           }
    
           public int Count
           {
    
               get { return _CountMember; }
           }
    
           public void ClearCount()
           {
               _CountMember = 0;
               _FlagFull = false;
           }
    
         
           public T ElementAt(int index)
           {
               if ((index >= plainBuffer.Length) || (index < 0))
                   throw new IndexOutOfRangeException();
    
                indexLoc = (_startIndex -1 - index);
            
               if ((indexLoc) < 0)
                indexLoc += plainBuffer.Length;
    
               return plainBuffer[indexLoc];
           }
    
         
           public void InsertBackwards(T newItem)
           {
               plainBuffer[_startIndex] = newItem;
    
               if (_startIndex >= plainBuffer.Length) { _CountMember = plainBuffer.Length; _FlagFull = true; }
               if (_startIndex == plainBuffer.Length - 1)
               {
                   _startIndex = 0;
                   _CountMember = plainBuffer.Length;
                   _FlagFull = true;
               }
               else
               {
                   _startIndex++;
                 
                
    
               }
               if (_FlagFull == false) _CountMember = _startIndex; // пока коллекция не полна количество членов равно стартовому индексу
           }
       }

    А по многопоточности, код же должен последовательно считаться. Так что здесь этого делать нельзя. Да и обращения к массиву должны быть последовательны и причины вылета не понятны из-за этого. Как количество определенных операций последовательных что-то может переполнить?

    Много коллекций работают на этом классе и без сбоев, а одна не хочет.


    Eugene



    23 августа 2013 г. 9:42