Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.12.23;
Скачать: CL | DM;

Вниз

Как сохранить значение в свойстве класса?   Найти похожие ветки 

 
AndrewK ©   (2003-12-10 00:53) [0]

Доброго времени суток, господа!

Посоветуйте, пожалуйста, что делать.

Проблема вот в чем:
Есть класс для обработки текстового потока который обрабатывает ряд последовательных шагов.
На "старт" и "стоп" выполнения повешаны события. Каждый шаг имеет свой таймаут для устранения
зависания. Обработка потока идет через метод AddToFlow (S : String) который вызывается основным
приложением.

Вот выдержки из кода:

...
tFlowProcessor = class
private
fFlowDescr : tFlowDescriptionList; // Список шагов с параметрами выполнения
fTimer : TTimer;
fCurStepIndex : Integer; // Индекс шага, который выполняется в настоящий момент
Buf : String;
fBufProcessEnabled : Boolean; // Флаг, определяющий можно или нет обрабатывать принятый пакет
procedure DoTimerAction (Sender : TObject); // Обработчик для таймера на таймаут
procedure ProcessBuffer; // Процедура обработки принятого пакета (Buf)
public
procedure AddToFlow (Packet : String); // Метод добавления строки Packet в накопитель Buf
procedure Start; // Начинает работу с первого элемента
procedure Stop; // Завершает работу
procedure StartReceiveInfo; // Настраивает сласс на ожидение и обработку пакета информации
end;


...

procedure tFlowProcessor.AddToFlow (Packet : String);
begin
// Добавление строки в накопитель
Buf := Buf + Packet;
// Проверка накопителя на наличие ожидаемых пакетов
ProcessBuffer;
end;

procedure tFlowProcessor.ProcessBuffer;
var vFlowItem : tFlowDescriptionItem;
begin
if not fBufProcessEnabled then Exit;
vFlowItem := fFlowDescr.GetItem(fCurStepIndex);
if vFlowItem.Text = Buf then begin
//.. что-то сделать
end;
end;

procedure tFlowProcessor.DoTimerAction (Sender : TObject);
var vFlowItem : tFlowDescriptionItem;
begin
fTimer.Enabled := False;
vFlowItem := fFlowDescr.GetItem(fCurStepIndex);
//... Что-то еще
end;

procedure tFlowProcessor.StartReceiveInfo;
begin
fTimer.Enabled := False;
fTimer.Interval := 5000;
Buf := "";
//fCurStepIndex на данном этапе определен и равен номеру выполняемого шага в списке fFlowDescr
fBufProcessEnabled := True;
fTimer.Enabled := True;
end;


Проблема вот в чем. Я вызываю StartReceiveInfo где устанавливаю таймер, который прекратит ожидание
через 5 сек, очищаю накопитель, разрешаю обработку принятого пакета и запускаю таймер. С этого момента
считаю, что процесс приема и обработки начался. Если таймер отработал и была вызвана процедура DoTimerAction,
которая привязана к событию OnTimer, то fCurStepIndex определен и равен тому, что было на момент начала
процесса приема. Если в процессе ожидания внешним модулем была вызвана процедура AddToFlow, которая обновит
накопитель и попробует его обработать процедурой ProcessBuffer, то ничего не получиться, так как в процедуре
ProcessBuffer fCurStepIndex уже не определена, точнее равна тому значению, которым она была проинициализирована
при конструировани класса. Аналогичный результат происходит если хранить указатель на обрабатываемый в данный
момент шаг, если хранить номер или указатель в каком-нибудь внутреннем классе, например в fFlowDescr. Если
использовать внешнюю к классу глобальную переменную, то все работает, но этот вариант не подходит.

Вот такая проблемка. Можно ли как-нибудь определить в классе свойство, которое бы играло роль глобальной переменной
для класса и не сбрасывалось в начальное само по себе.

Прошу прощения за длинный текст, но короче не смог. Нахожусь под впечатлением от этого открытия. Если кто знает
лечение проблемы, пожалуйста поделитесь.


 
ЮЮ ©   (2003-12-10 03:27) [1]

>fCurStepIndex уже не определена, точнее равна тому значению, которым она была проинициализирована
при конструировани класса

Этого не может быть. Private поля экземпляра класса изменяются только в методах экземпляра и если они не те, что ожидались, значит где-то в одном из методов ты их переопределяешь


 
AndrewK ©   (2003-12-10 10:32) [2]

Я тоже думал, что невозможно.
Делал такой опыт
Есть код контсруктора:

constructor tFlowProcessor.Create;
begin
inherited;
fCurStepIndex := 100;
...
end;


fCurStepIndex по логике программы у меня нигде не может быть равна 100.

procedure tFlowProcessor.StartReceiveInfo;
begin
fTimer.Enabled := False;
fTimer.Interval := 5000;
Buf := "";
!!! Вот здесь fCurStepIndex равно ожидаемому, например 2. !!!
//fCurStepIndex на данном этапе определен и равен номеру выполняемого шага в списке fFlowDescr
fBufProcessEnabled := True;
fTimer.Enabled := True;
end;

procedure tFlowProcessor.AddToFlow (Packet : String);
begin
!!! А вот здесь fCurStepIndex = 100 !!!
// Добавление строки в накопитель
Buf := Buf + Packet;
// Проверка накопителя на наличие ожидаемых пакетов
ProcessBuffer;
end;


Либо меня уже глючит, либо здесь что-то не так.


 
AndrewK ©   (2003-12-10 10:39) [3]

Забыл добавить. При вызове метода Start делаю fCurStepIndex := 0.


 
AndrewK ©   (2003-12-10 13:27) [4]

Никто ничего посоветовать не может?


 
Erik ©   (2003-12-10 15:29) [5]

Баг однозначно у тебя в коде. Переделай алгоритм на более логичный. Неспользуй таймер он тебе ненужен. В
procedure tFlowProcessor.ProcessBuffer
if Not (GetTickCount - MyCount > 60 * 1000) then
работаем......

MyCount - заполни при старте метода.



Страницы: 1 вся ветка

Текущий архив: 2003.12.23;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.023 c
14-75374
marconi
2003-11-28 22:39
2003.12.23
странности блочной записи BlockWrite


11-75136
Gandalf
2003-04-10 15:42
2003.12.23
Всяк сюда входящий...


14-75386
Igorek
2003-11-27 21:15
2003.12.23
Что делать, когда все в лом?


1-75239
ertong
2003-12-10 18:11
2003.12.23
Проблемы с try


7-75406
Rentgen
2003-10-21 17:34
2003.12.23
canclose:=false