Форум: "Основная";
Текущий архив: 2004.02.13;
Скачать: [xml.tar.bz2];
ВнизОрганизация стэка Найти похожие ветки
← →
h0use (2004-02-04 15:49) [0]Уважаемые мастера, благодарю за ответ на пред. вопрос.
Возник у меня следующий:
В программе идет асинхронное чтение данных. Есть функция которая возвращает булеву переменную зависящую от результата прочтения данных из порта, однако она зависает привожу код :
Функция возвращения результата:
function TfmMain.GetTableState(ATable:Byte;AIndex:Integer):Boolean;
var
AMsg:TCommBlock;
Cmd : String;
CmdPos:Integer;
begin
Result:=False;
try
AMsg.Command:=cmdSystem;
AMsg.Argument1:=argSYSGetState;
AMsg.Argument2:=ATable;
AMsg.Msg:=IntToStr(AIndex);
SendMsg(AMsg);
Screen.Cursor:=crHourGlass;
Cmd:="WaitTableState";
CmdPos:=Stack.Add(Cmd);
while True do
if Stack.Strings[CmdPos]<>Cmd then
begin
Cmd:=Stack.Strings[CmdPos];
Stack.Delete(CmdPos);
Break;
end
else Application.ProcessMessages;
Screen.Cursor:=crDefault;
if Cmd="0" then Result:=False
else Result:=True;
except
on e: Exception do
end; // try/except
end; // GetTableState
Процедура получающая значение:
procedure TfmMain.SystemGetState(AMsg:TCommBlock);
var
I: Integer;
begin
for I := 0 to Stack.Count - 1 do
if Stack.Strings[I]="WaitTableState" then
begin
Stack.Strings[I]:=AMsg.Msg;
Break;
end;
end; // SystemGetState
И все это не работает :( В чем грабли?
PS Stack: TStringList;
← →
h0use (2004-02-04 16:04) [1]Есть идеи или недостаточно информации?
← →
h0use (2004-02-04 16:37) [2]Мастера, проявите внимание, работа стоит и восполенный мозг не может найти решения :(
← →
Тимохов (2004-02-04 16:49) [3]Решил проявить внимание.
Вопросы:
1. Чего ты добиваешься - что должно работать.
2. Что такое sendmsg.
← →
h0use (2004-02-04 16:52) [4]1. Должна работать функция (она виснет на while не смотря на то, что вторая процедура отрабатывает свое)
2. SendMsg - процедура отсылки сообщения, результат обработки которого и отлавливает вторая процедура (точнее ей он передается)
← →
Тимохов (2004-02-04 16:56) [5]Думаю, что вы были правы в h0use © (04.02.04 16:04) [1].
← →
h0use (2004-02-04 16:58) [6]Если бы я был прав, то у меня не висла бы функция :(
← →
h0use (2004-02-04 17:00) [7]Алгоритм проги прост...она посылает сообщения серваку и получает от него ответы, ответы могут быть не последовательны (т.е. не факт что первым прийдет ответ на последний запрос. Собственно два метода и представлено в одном посылается запрос на сервак, во втором обрабатывпается ответ...но в первый должен ждать, пока ответ обработается и только после этого продолжить работу.
← →
Тимохов (2004-02-04 17:01) [8]
> h0use © (04.02.04 16:58) [6]
Имелось в виду, что инфы недостаточно.
← →
h0use (2004-02-04 17:06) [9]Дык написал уже, что еще не хватает?
← →
AKul (2004-02-04 17:05) [10]Без дополнительной информации трудновато. Мои предположения:
SendMsg - синхронная отсылка сообщения
TfmMain.SystemGetState отрабатывается в процедуре SendMsg (выход из нее будет осуществлен после обработки этого посланного), а не после вызова Application.ProcessMessages.
Т.е. "WaitTableState" добавиться после обработки посланного сообщения.
Передавайте сообщения ассинхронно или используй потоки.
← →
Тимохов (2004-02-04 17:06) [11]У вас откровенная алгоритмическая ошибка
здесь
Cmd:="WaitTableState";
CmdPos:=Stack.Add(Cmd);
while True do
if Stack.Strings[CmdPos]<>Cmd then
begin
Cmd:=Stack.Strings[CmdPos];
Stack.Delete(CmdPos);
Break;
end
else Application.ProcessMessages;
Если забыть про метод SystemGetState, то очевидно, что данный while бесконечен.
Если взять в учет SystemGetState (я так понял, что это обработчик события), то у вас также может быть ошибка, если в стеке лежат строки
"WaitTableState",
"bla-bla-bal",
"WaitTableState"
При том, что в пермов методе CmdPos = 2.
Ячно, что это навсегда.
Модернизируйте логику.
← →
Семен Сорокин (2004-02-04 17:09) [12]for I := Stack.Count - 1 downto 0 do
← →
Тимохов (2004-02-04 17:11) [13]Все-таки не очень ясна логика.
Кто может геренить событие SystemGetState(AMsg:TCommBlock) - только ты в своем методе SendMsg или где-то еще.
Если только ты в методе SendMsg, то 10 прав. Если кто-то еще может, то, возможно, я прав в 11.
Учти еще замечание 12 - также верное.
← →
Erik (2004-02-04 17:15) [14]Криво както все это. Используй потоки и логика проще будет.
← →
h0use (2004-02-04 17:17) [15]
> Семен Сорокин ©
Не помогает...
Упростим задачу: пердположим есть кнопка на форме и есть процедура, которая должна продолжить свое выполнение после того как кнопка нажметься.
Как бы вы делали это?
← →
AKul (2004-02-04 17:22) [16]
> h0use © (04.02.04 17:17) [15]
>
> Не помогает...
[10], А SendMsg заменить на ассинхронную передачу сообщения пробовали?
← →
Тимохов (2004-02-04 17:23) [17]ButtonClicked := false; // global var
while true do
begin
if ButtonClicked then break;
application.processmessages();
end;
....// продолжнаем действия
procedure tform1.buttonclick(....);
begin
buttonclicked := true;
end;
← →
AKul (2004-02-04 17:25) [18]
> Упростим задачу: пердположим есть кнопка на форме и есть
> процедура, которая должна продолжить свое выполнение после
> того как кнопка нажметься.
>
> Как бы вы делали это?
Самый простой способ - описать процедуру в TThread.Execute, а по нажатию кнопки создавать и запускать поток (TThread.Create)....
← →
h0use (2004-02-04 17:37) [19]
> AKul © (04.02.04 17:22) [16]
Синхронно не получится, так как паралельно клиент получает другу информацию от сервера.
← →
AKul (2004-02-04 17:44) [20]
> h0use © (04.02.04 17:37) [19]
> Синхронно не получится, так как паралельно клиент получает
> другу информацию от сервера.
Насколько я понял, у Вас и так синхронная посылка сообщения, а я спрашивал об ассинхронной.
У меня складывается впечатление, что Вы не понимаете разницы между функциями SendMessage и PostMessage.
← →
h0use (2004-02-04 17:46) [21]Тут выяснилась проблемка, я получаю сообщение от сервака и обрабатываю его методом посылки ТMessage. Сервак ответ посылает но клиент не обрабатывает сообщение...вообще в эту процедуру не попадает :(
← →
AKul (2004-02-04 17:55) [22]
> h0use © (04.02.04 17:37) [19]
Еще раз повторяю:
> function TfmMain.GetTableState(ATable:Byte;AIndex:Integer):Boolean;
> var
> AMsg:TCommBlock;
> Cmd : String;
> CmdPos:Integer;
> begin
> Result:=False;
> try
> AMsg.Command:=cmdSystem;
> AMsg.Argument1:=argSYSGetState;
> AMsg.Argument2:=ATable;
> AMsg.Msg:=IntToStr(AIndex);
> SendMsg(AMsg); // Если это синхронная передача
// т.е. SendMessage(Self.Handle,...
// то в этом месте вызовется
// TfmMain.SystemGetState и выполнение
// продолжить после обработки этого сообщения
> Screen.Cursor:=crHourGlass;
> Cmd:="WaitTableState"; // А сообщение SystemGetState уже отработало
> CmdPos:=Stack.Add(Cmd);
> while True do // и бесконечный цикл, т.к.
// TfmMain.SystemGetState уже отработало
> if Stack.Strings[CmdPos]<>Cmd then
> begin
> Cmd:=Stack.Strings[CmdPos];
> Stack.Delete(CmdPos);
> Break;
> end
> else Application.ProcessMessages;
> Screen.Cursor:=crDefault;
> if Cmd="0" then Result:=False
> else Result:=True;
> except
> on e: Exception do
> end; // try/except
> end; // GetTableState
← →
AKul (2004-02-04 17:57) [23]
> h0use © (04.02.04 17:46) [21]
> Сервак ответ
> посылает но клиент не обрабатывает сообщение...вообще в
> эту процедуру не попадает :(
Подробнее...
Код посылки, код обработки....
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.02.13;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.011 c