Indy синхронизировать ServerTCPExecute
Я использую компонент TIDTCPServer. Как я поняла событие ServerTCPExecute(AContext: TIdContext)
не синхронизируется. Каков наилучший способ синхронизации? Мне нужно, чтобы данные отправлялись в основной поток и возвращались к формату ответа.
Я использую Indy 10.5.8.0.
Способ 1
Это что-то вроде этого, я должен иметь дело с критическими секциями для передачи данных из несинхронизированной функции в приложение?
var data:string;
.
.
.
procedure MainThreadProcedure;
begin
...
end;
.
.
.
procedure IdTCPServerExecute(AContext: TIDContext);
var tmp: string;
begin
.
.
.
EnterCriticalSection(cs);
data:= tmp;
TIdYarnOfThread(AContext.Yarn).Thread.Synchronize(MainThreadProcedure);
LeaveCriticalSection(cs);
end;
2 ответа
Правильный способ заключается в использовании Indy's TIdSync
вместо доступа к внутренним потокам Indy, например:
uses
..., IdSync;
type
TMySync = class(TIdSync)
protected
procedure DoSynchronize; override;
public
data: string;
end;
procedure TMySync.DoSynchronize;
begin
// this runs in the main thread
// use data as needed...
end;
procedure IdTCPServerExecute(AContext: TIDContext);
var
tmp: string;
sync: TMySync;
begin
tmp := ...;
sync := TMySync.Create;
try
sync.data := tmp;
sync.Synchronize;
finally
Sync.Free;
end;
end;
Просто будьте осторожны с любой синхронизацией, которую вы делаете, будь то TIdSync
или же TThread.Synchronize()
, Если основной поток пытается деактивировать сервер во время синхронизации сервера с основным потоком, вы заблокируете как основной поток, так и сервер.
В моем приложении я использую этот код:
procedure MainThreadProcedure;
begin
...
end;
.
.
.
procedure IdTCPServerExecute(AContext: TIDContext);
begin
TIdYarnOfThread(AContext.Yarn).Thread.Synchronize(MainThreadProcedure);
end;
Обязательно используйте критическую секцию или другой объект синхронизации, если вам нужен доступ к переменным основного потока в ServerTCPExecute