Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.04.2016, 07:30   #1
sosyamba
 
Регистрация: 26.04.2016
Сообщений: 5
Восклицание IdTCPServer повисание приложения

Все привет!

Имеется сервер IdTCPServer. При подключении к серверу клиента, клиент добавляется в список Clients: TThreadList;

Код:
  TClient = class(TObject)
    NE: String;
    CN: String;
    Connected: TDateTime;
    LastAction: TDateTime;
    Context: TIdContext;
  end;
Когда я хочу получить доступ к списку в обработчике IdTCPServer.OnExecute я использую такую конструкцию:

Код:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
.....
  List: TList;
  X: Integer;
begin
.....
  List := Clients.LockList;
  try
    X := List.Count;
  finally
    Clients.UnLockList;
  end;
.....
и вроде все нормально, днями работает нормально, но когда я точно такую же конструкцию ставлю в обработчике TTimer у меня через пару минут приложение наглухо повисает.

Последний раз редактировалось sosyamba; 26.04.2016 в 07:40.
sosyamba вне форума Ответить с цитированием
Старый 26.04.2016, 11:45   #2
BARNEY
Участник клуба
 
Регистрация: 23.04.2009
Сообщений: 1,058
По умолчанию

IdTCPServer1Execute на каждое подключение САМ создаёт отдельный поток, таймер такого не умеет
Если вам человек помог, не стесняйтесь говорить спасибо (весы под аватаром)
BARNEY вне форума Ответить с цитированием
Старый 26.04.2016, 14:23   #3
sosyamba
 
Регистрация: 26.04.2016
Сообщений: 5
По умолчанию

Цитата:
Сообщение от BARNEY Посмотреть сообщение
IdTCPServer1Execute на каждое подключение САМ создаёт отдельный поток, таймер такого не умеет
это и понятно. посмотрите что я хочу получить в таймере (количество клиентов).
sosyamba вне форума Ответить с цитированием
Старый 26.04.2016, 15:43   #4
BARNEY
Участник клуба
 
Регистрация: 23.04.2009
Сообщений: 1,058
По умолчанию

может юзать System.Classes.TThread.Synchronize
или critical section delphi
Если вам человек помог, не стесняйтесь говорить спасибо (весы под аватаром)
BARNEY вне форума Ответить с цитированием
Старый 26.04.2016, 16:10   #5
sosyamba
 
Регистрация: 26.04.2016
Сообщений: 5
По умолчанию

Цитата:
Сообщение от BARNEY Посмотреть сообщение
может юзать System.Classes.TThread.Synchronize
или critical section delphi
Код:
  List := Clients.LockList;
  try
    X := List.Count;
  finally
    Clients.UnLockList;
  end;
вот этот код еще и оборачивать в TCriticalSection? получается двойная блокировка. так же вроде нельзя.

почему то происходит конфликт между потоками и основным потоком программы.
между потоками в IdTCPServer конфликта нет, стабильно работают.
как только включаю таймер программа зависает через пару минут.
sosyamba вне форума Ответить с цитированием
Старый 26.04.2016, 17:08   #6
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,689
По умолчанию

Не нужно ещё одну КС. В приведённом отрывке кода нет ответа.
Вероятно, LockList из другого потока блокирует главный поток (пусть даже на доли секунды) во время очередного тика таймера, но сразу после этого идёт обращение к форме или её полям (переменным класса и т.п.). Таким образом поток заблокировал форму (т.к. таймер скорее всего на форме), но ждёт доступа к ней чтобы что-то прочитать/записать с неё. Это и приводит к блокировке блокировщика.

Писано наугад, т.к. подробных кодов нет. Но если полный код был, то всё равно написал то же самое, т.к. было бы лень ))
eoln вне форума Ответить с цитированием
Старый 27.04.2016, 14:15   #7
sosyamba
 
Регистрация: 26.04.2016
Сообщений: 5
По умолчанию

Разрешено ли так делать в обработчике IdTCPServer1.OnExecute вызвать IdTCPServer1.Contexts.LockList; ?
может из за этого что глючит?
sosyamba вне форума Ответить с цитированием
Старый 27.04.2016, 15:51   #8
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,689
По умолчанию

Делать можно. Может ли глючить? - Глючить может даже от мёда, если его холодной водой запивать. По отдельности можно многое, а вот в тандеме нет.
На лицо двойная блокировка. Между любыми LockList/UnLockList нельзя ничего синхронизировать (или лезть в другие потоки без синхронизации).
P.S. Можно безопасно синхронизировать только то, что не имеет общих ресурсов из области КС
eoln вне форума Ответить с цитированием
Старый 30.04.2016, 13:40   #9
sosyamba
 
Регистрация: 26.04.2016
Сообщений: 5
По умолчанию

OnExecute - выполняется НЕ в основном потоке приложения
а OnDisconnect ? в основном или нет?
sosyamba вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
IdTCPServer и IdTCPClient -=<_Makap_>=- C++ Builder 0 08.12.2012 18:41
idTCPServer Anatoliy24 Работа с сетью в Delphi 7 12.02.2011 11:40
idTCPserver и кирилица BARNEY Работа с сетью в Delphi 7 21.10.2010 14:47
IdTCPServer Pankhammer Работа с сетью в Delphi 0 30.04.2010 00:14
IdTCPServer Exception Comer_Jus Работа с сетью в Delphi 2 25.06.2008 22:23