powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TIdTCPServer.OnExecute & TQueue
25 сообщений из 39, страница 1 из 2
TIdTCPServer.OnExecute & TQueue
    #40110377
antox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запускаю сервер TIdTCPServer и отлавливаю на OnExecute входящее от клиента данные, всё нормально, но...

Если в OnExecute принять данные от клиента и отправить их в функцию, которая вызывает, например, ShowMessge или ShowModal , то приложение зависает...

Так работает нормально:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure DoOnIndyExecute();
var
  s: string;
begin
  s := AContext.Connection.Socket.ReadLn(IndyTextEncoding(IdTextEncodingType.encUTF8));
  
  showCaption(s);
end;

procedure showCaption(s: string);
begin
  form1.caption := s;
end;



Так начинает виснуть:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
procedure DoOnIndyExecute();
var
  s: string;
begin
  s := AContext.Connection.Socket.ReadLn(IndyTextEncoding(IdTextEncodingType.encUTF8));
  
  showForm(s);
end;

procedure showForm(s: string);
var
  s2: boolean;
begin
  form1.edit1.text := s;
  if form1.ShowModal then s2 := form1.edit1.text else s2 := s;
end;



Я так понимаю, что надо полученные данные в DoOnIndyExecute как-то ставить в очередь, а потом собирать из очереди в showForm или вообще не туда?
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110381
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
antox,
найди книжку Григтрьева "О чем не пишут в книжках по Дельфи", там tcp сервера руками реализуют, с подробными разъяснениями.
Нафига тебе эти инди...
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110384
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
"О чём не пишут в книгах по Delphi." А. Б. Григорьев
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110385
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
antox*ShowMessge *или *ShowModal*, то приложение зависает...

Не зависает, а показывает диалог или форму и ждёт пока пользователь их закроет.
Внезапно, но именно это и написано в справке по данным функциям.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110386
antox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
"О чём не пишут в книгах по Delphi." А. Б. Григорьев


Ага, нашел, почитаю... Спасибо
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110388
antox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

antox*ShowMessge *или *ShowModal*, то приложение зависает...

Не зависает, а показывает диалог или форму и ждёт пока пользователь их закроет.
Внезапно, но именно это и написано в справке по данным функциям.


После того, как закрываешь модальное окно, приложение не реагирует на клики мыши и клавиатуры, даже закрыть его не получается, но в диспетчере задач всё норм, приложение типа отвечает
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110392
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот поэтому-то их нельзя показывать из фоновых потоков (без основательных
знаний). Отладчик в руки и смотри чем каждый из потоков после закрытия занят.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110397
antox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Вот поэтому-то их нельзя показывать из фоновых потоков (без основательных
знаний). Отладчик в руки и смотри чем каждый из потоков после закрытия занят.


Так-так.., а он в отдельном потоке OnExecute обрабатывает или это мне надо отдельный поток создавать?
Я-то все в основном делаю
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110399
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
antoxа он в отдельном потоке OnExecute обрабатывает

А вот это-то тебе и поможет выяснить отладчик. Если сумеешь научиться им
пользоваться.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110402
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
antox
Dimitry Sibiryakov

Вот поэтому-то их нельзя показывать из фоновых потоков (без основательных
знаний). Отладчик в руки и смотри чем каждый из потоков после закрытия занят.


Так-так.., а он в отдельном потоке OnExecute обрабатывает или это мне надо отдельный поток создавать?
Я-то все в основном делаю
В отдельном потоке.

Из справки по TIdTCPServer.OnExecute Event
OnExecute receives a TIdContext argument that represents the task for the client connection, and contains a TIdTCPConnection instance for the client connection, and the thread or fiber that controls execution of the task. A protected procedure in the server that triggers OnExecute is assigned to the TIdContext, and eventually the thread or fiber acquired from the Scheduler for the server.


Из справки по TIdTCPServer
TIdTCPServer allows multiple simultaneous client connections, and allocates a separate unit of execution for each client connecting to the server. Each client connection represents a task that is managed by the Scheduler for the server. Listener threads use the Scheduler to create an executable task for each client connection.

The Scheduler handles creation, execution, and termination of tasks for client connections found in Contexts. The ContextClass property indicates the type of executable task created for client connections and added to Contexts.

There are basically two types of Schedulers available for TIdTCPServer: Thread-based and Fiber-based. Each is designed to work with a specific type of executable task that represents the client connections. There are further Scheduler refinements that allow a pool of pre-allocated Threads, or Threads which perform scheduling for dependent Fibers.

The default Scheduler implementation in TIdTCPServer uses a Thread to represent each client connection. Threads are a common feature found on all platforms and Operating Systems hosting the Indy library.
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110414
antox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Похоже, отдельный поток, после входа в OnExecute, пробегает до конца, далее устанавливается на

Код: pascal
1.
s := AContext.Connection.Socket.ReadLn(IndyTextEncoding(IdTextEncodingType.encUTF8));



и ждет новых данных

соответственно, если в OnExecute после AContext.Connection.Socket.ReadLn(IndyTextEncoding(IdTextEncodingType.encUTF8)); вызывается модальное окно, то тут и происходит затуп, выполнение останавливается вместо того, чтобы вернуться на

Код: pascal
1.
s := AContext.Connection.Socket.ReadLn(IndyTextEncoding(IdTextEncodingType.encUTF8)); 



и слушать дальше.

Т.е. надо писать в глобальную переменную и хотя бы для начала по таймеру проверять s.length > 0

Код: pascal
1.
s := AContext.Connection.Socket.ReadLn(IndyTextEncoding(IdTextEncodingType.encUTF8));



читать из переменной данные и задавать пустую строку s := '';
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110418
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, надо таки прочитать документацию как всей этой машинерией пользоваться
правильно. Выше уже цитировали кусок.

PS: Хотя на мой вкус проще выкинуть всю эту индюшатину в полном составе.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110423
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
antox,

у тебя же компонент TIdTCPServer на формочке лежит? Если да - то добавь на форму обработчик сообщения WM_STRPROCESS:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
const
  WM_STRPROCESS = WM_USER + 101;

TForm1 = class(TForm)
...
  private
    procedure WMStrProcess(var aMessage: TMessage); message WM_STRPROCESS;
end;
...
implementation

procedure TForm1.WMStrProcess(var aMessage: TMessage);
var
  fStr: string;
begin
  WPARAM(fStr) := aMessage.WParam;
  ShowMessage(fStr);
end;



а из OnExecute не ShowMessage(строка) зови, а ShowStr(строка). Функцию ShowStr() определи тут же:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  TForm1 = class(TForm)
  private
    procedure ShowStr(aStr: string);
...
  end;
...

implementation

procedure TForm1.ShowStr(aStr: string);
var
  fStr: string;
begin
  fStr := aStr;
  PostMessage(Self.Handle, WM_STRPROCESS, WPARAM(Pointer(fStr)), 0);
  WPARAM(fStr) := 0;
end;


:)
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110436
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъPostMessage(Self.Handle, WM_STRPROCESS, WPARAM(Pointer(fStr)), 0);

С PostMessage так нельзя: до главного потока долетит ссылка на мусор от которого
тому поплохеет. С SendMessage - можно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110450
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

а строка-то в куче лежит. :)
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110452
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъа строка-то в куче лежит. :)

Да. И это место освобождается сразу после выхода из метода, где она объявлена.
Что, неожиданно для нубов, случается ДО того, как сообщение дойдёт до главного
потока.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110454
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov
И это место освобождается сразу после выхода из метода, где она объявлена.

Не.
Код: pascal
1.
  WPARAM(fStr) := 0;
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110458
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ WPARAM(fStr) := 0;

Прелестная утечка памяти.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110459
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

тебе сегодня не угодить.
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110461
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В любой день я буду ругаться на говнокод, который нубы будут копипастить в
продакшен.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110489
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Прелестная утечка памяти.
Нет там утечек. И код работать будет.
ъъъъъ
Код: pascal
1.
  WPARAM(fStr) := 0;

Отключаем финализацию в ShowStr
ъъъъъ
Код: pascal
1.
WPARAM(fStr) := aMessage.WParam;

Присваиваем здесь строку без увеличения счетчика ссылок. При выходе из WMStrProcess строка финализируется.

Я бы еще добавил Finalize в WMStrProcess. Просто чтобы работало всегда, а не до следующего изменения логики компилятора
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TForm1.WMStrProcess(var aMessage: TMessage);
var
  fStr: string;
begin
  Finalize(fStr);  // или fStr := '';
  WPARAM(fStr) := aMessage.WParam;
  ShowMessage(fStr);
end;
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110492
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_,

ну, теоретически... если сообщение как-то потеряется, то вот вам и утечка. :)
Можно придумать ситуацию, если очень хочется.
...
Я данной схемой межнитевого взаимодействия пользуюсь, давно. Не нужно синхронизаций, просто и удобно.
И, конечно, можно не только окну слать, а и в очередь треда, но с окном в дельфи обычно проще: окна почти всегда есть, и message - методы, для лентяев... :)
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110494
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъМожно придумать ситуацию, если очень хочется.

Например, когда sizeof(WPARAM) <> sizeof(LPARAM) <> sizeof(Pointer).
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110497
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

точно, в Win3.1 работать не будет! :)
...
Рейтинг: 0 / 0
TIdTCPServer.OnExecute & TQueue
    #40110502
antox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
antox,

у тебя же компонент TIdTCPServer на формочке лежит? Если да - то добавь на форму обработчик сообщения WM_STRPROCESS:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
const
  WM_STRPROCESS = WM_USER + 101;

TForm1 = class(TForm)
...
  private
    procedure WMStrProcess(var aMessage: TMessage); message WM_STRPROCESS;
end;
...
implementation

procedure TForm1.WMStrProcess(var aMessage: TMessage);
var
  fStr: string;
begin
  WPARAM(fStr) := aMessage.WParam;
  ShowMessage(fStr);
end;



а из OnExecute не ShowMessage(строка) зови, а ShowStr(строка). Функцию ShowStr() определи тут же:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  TForm1 = class(TForm)
  private
    procedure ShowStr(aStr: string);
...
  end;
...

implementation

procedure TForm1.ShowStr(aStr: string);
var
  fStr: string;
begin
  fStr := aStr;
  PostMessage(Self.Handle, WM_STRPROCESS, WPARAM(Pointer(fStr)), 0);
  WPARAM(fStr) := 0;
end;


:)


Нет, без формы, создается динамически :(
...
Рейтинг: 0 / 0
25 сообщений из 39, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TIdTCPServer.OnExecute & TQueue
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]