Форум: "Основная";
Текущий архив: 2003.12.23;
Скачать: [xml.tar.bz2];
ВнизКак сохранить значение в свойстве класса? Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.008 c