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

Вниз

Виснет TidHTTPServer при попытке его остановки.   Найти похожие ветки 

 
DVM ©   (2008-06-09 14:19) [0]

При переходе на Indy10 стал виснуть сервер при попытке его остановки, если есть подключенные клиенты. Останавливается как обычно: IdHTTPServer.Active := false;

Сервер отправляет данные клиентам. Данные бесконечны, поэтому обработчик IdHTTPServerCommandGet выглядит примерно так:

procedure TfrmMain.IdHTTPServerCommandGet(AContext: TIdContext;
 ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
 ....
 while AContext.Connection.Connected do
   begin
     .... тут отсылаем данные ....
     sleep(0);
     ....
   end;
 ...
end;

В предыдущей версии Indy все работало. В новой висит на цикле. Если цикл убрать, то не виснет. Виснет даже с пустым циклом.
Как с этим бороться?


 
Поросенок Винни-Пух ©   (2008-06-09 14:28) [1]

Что-то типа
трай
сессионнс.локлист
фор нуль до конца ду гасить колиентов
файнали
анлоклист
енд


 
Anatoly Podgoretsky ©   (2008-06-09 14:43) [2]

> DVM  (09.06.2008 14:19:00)  [0]

В  коде не видать IdHTTPServer.Active := false;


 
DVM ©   (2008-06-09 14:45) [3]


> Anatoly Podgoretsky ©   (09.06.08 14:43) [2]

procedure TfrmMain.btnStopClick(Sender: TObject);
var
 Lst: TList;
begin
 IdHTTPServer.StopListening;
 Lst := IdHTTPServer.Contexts.LockList;
 try
   while Lst.Count > 0 do
     TIdContext(Lst.Items[0]).Connection.Disconnect;
 finally
   IdHTTPServer.Contexts.UnlockList;
 end;
 IdHTTPServer.Active := false;
end;

Виснет все равно.


 
Anatoly Podgoretsky ©   (2008-06-09 15:09) [4]

Теперь не видать удаление элементов из Lst или этим Инди занимается.
Второе, а ты точно дождался окончания операции Disconnect для каждого элемента списка, это может занимать очень много времени.
Почему бы для отладки не выводить в метку значение Lst.Count? Тогда сраду будет видно.
Третье, а в позицию IdHTTPServer.Contexts.UnlockList или IdHTTPServer.Active := false; управление попадает, это же ты должен провести отладку, а не мы.
Ответь на какой строке у тебя зависает?


 
DVM ©   (2008-06-09 15:24) [5]


> Теперь не видать удаление элементов из Lst или этим Инди
> занимается.

Этим должна заниматься инди вообще то. Я немного неправильно написал вверху, наверное, лучше так, наверное, но это дела не меняет:

for i := 0 to Lst.Count - 1 do
 TIdContext(Lst.Items[i]).Connection.Disconnect;


> Ответь на какой строке у тебя зависает?

IdHTTPServer.Active := false;


> Второе, а ты точно дождался окончания операции Disconnect
> для каждого элемента списка, это может занимать очень много
> времени.

Нет, не дожидаюсь. Но дело в том, что IdHTTPServer.Active := false; сам по идее должен ждать окончания всех соединений, он и ждет. И не дожидается.


 
Anatoly Podgoretsky ©   (2008-06-09 15:44) [6]

> DVM  (09.06.2008 15:24:05)  [5]

Неправильно ты написал сейчас, готовься к исключению.

>> Ответь на какой строке у тебя зависает?

> IdHTTPServer.Active := false;

Означает ли, что ты сюда получаешь управление?


 
DVM ©   (2008-06-09 15:53) [7]


> Неправильно ты написал сейчас, готовься к исключению.

Лист залочен и не изменится, какие исключения? Я лишь оповещаю потоки, что пора закругляться. Воообще все эти строки TIdContext(Lst.Items[i]).Connection.Disconnect;
лишние. В предыдущей версии Инди все работало и само прекрасно завершалось одной строкой IdHTTPServer.Active := false;


> Означает ли, что ты сюда получаешь управление?
>

Да. И дальше пошло поехало в дебри инди, в которых я погряз, пытаясь разобраться где там зависает.


 
Поросенок Винни-Пух ©   (2008-06-09 16:06) [8]

Я лишь оповещаю потоки, что пора закругляться.

А им с их синхронными методами по барабану оповещения если конечно нет таймаутов


 
DVM ©   (2008-06-09 16:30) [9]


> А им с их синхронными методами по барабану оповещения если
> конечно нет таймаутов

Ну дык в каждом потоке, крутится мой цикл (см выше), который проверяет флаг Connected.

Я так понял вначале, что выполнение метода  TIdContext(Lst.Items[i]).Connection.Disconnect; аналогично TThread.Terminate в VCL и устанавливает флаг закругления. Оказывается все не так.


 
DVM ©   (2008-06-09 16:41) [10]

Вобщем, нашел я ошибку свою и решение.

В цикле было в коде подавление всех исключений без разбору:

while AContext.Connection.Connected do
begin
 ....
 try
   AResponseInfo.WriteContent;
 except
 end;
 ...
end;
 
что делало невозможным установку флага Connected со стороны потока, т.к. формально ошибок никаких не возникало (просто неоткуда). Странно, что это работало в предыдущей версии Инди. Если сделать выход по исключению, то все нормально работает.

while AContext.Connection.Connected do
begin
 ....
 try
   AResponseInfo.WriteContent;
 except
   exit;
 end;
 ...
end;


 
DVM ©   (2008-06-09 17:12) [11]

В догонку, может кому пригодится.

Еще более правильно и надежно подправить так:

while ((not (AContext.Yarn as TIdYarnOfThread).Thread.Terminated) and (AContext.Connection.Connected)) do

begin
  ...
end;



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

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

Наверх




Память: 0.49 MB
Время: 0.007 c
2-1261744269
vegarulez
2009-12-25 15:31
2010.02.28
вопрос про XML


15-1260999021
Юрий
2009-12-17 00:30
2010.02.28
С днем рождения ! 17 декабря 2009 четверг


1-1238564083
EgorovAlex
2009-04-01 09:34
2010.02.28
Как правильно прочитать значение из IADsUser


15-1260893769
ocean
2009-12-15 19:16
2010.02.28
Бунт машин


3-1235802388
Den
2009-02-28 09:26
2010.02.28
Соединение с сервером Firebird