실행할 때 응용 프로그램이 정지되는 이유를 찾으려고합니다. IdTCPServer1.Active : = False;Indy TCPServer Freeze : Active => False
클라이언트가 연결되어 있지 않아도 문제가 없습니다. 하나 이상의 클라이언트가 연결되면 동결됩니다.
누군가 내가 실수 한 부분을 찾을 수 있다면. (I 말해 ... 당신이 뭔가 다른 잘못을 참조하면, 델파이에 새로 온 사람, 또는 잘못된 방법으로 그 일을)
TLog = class(TIdSync)
protected
FMsg: String;
procedure DoSynchronize; override;
public
constructor Create(const AMsg: String);
class procedure AddMsg(const AMsg: String);
end;
procedure TLog.DoSynchronize;
begin
Form2.AddInfoDebugger('RECEPTION', FMsg);
end;
class procedure TLog.AddMsg(const AMsg : String);
begin
with Create(AMsg) do
try
Synchronize;
finally
Free;
end;
end;
constructor TLog.Create(const AMsg : String);
begin
FMsg := AMsg;
inherited Create;
end;
/// TFORM 2 ///
constructor TForm2.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
LoadIniConfiguration;
IdTCPServer1.ContextClass := TMyContext;
IdTCPServer1.DefaultPort := IndyServerPort;
DictionaryMessage := TDictionaryMessage.Create;
fSvrClose := False;
if fileexists(SaveFileName)
then
DictionaryMessage.LoadFromFile(SaveFileName);
UpdateListQuestions;
if IndyAutoStart
then
StartStopIndyServer;
// add info state debug save
if DebugConfigState
then
LabelStateDebugSave.Caption :=
'Sauvegarde des journaux sur disque: Activé'
else
LabelStateDebugSave.Caption :=
'Sauvegarde des journaux sur disque: Désactivé';
end;
procedure TForm2.FormClose(
Sender : TObject;
var action : TCloseAction);
var
iA : integer;
Context : TIdContext;
begin
if IdTCPServer1.Active
then
begin
fSvrClose := true;
IdTCPServer1.Active := False;
fSvrClose := False;
end;
end;
// ******
// ******INDY procedures START*******//
// ******
procedure TForm2.StartStopIndyServer;
begin
if not IdTCPServer1.Active
then
begin
IdTCPServer1.Active := true;
Form2.AddInfoDebugger('ONLINE',
'Server is now connected and ready to accept clients');
ListBoxClients.Clear;
ListBoxClients.Items.Add('Serveur');
UpdateCountClients;
Button1.Caption := 'Arret';
end
else
begin
fSvrClose := true;
IdTCPServer1.Active := False;
fSvrClose := False;
ListBoxClients.Clear;
Form2.AddInfoDebugger('Offline', 'Server is now disconnected');
Button1.Caption := 'Démarrer';
UpdateCountClients;
end;
end;
procedure TForm2.tsConnect(AContext : TIdContext);
begin
with TMyContext(AContext) do
begin
Con := Now;
if (Connection.Socket <> nil)
then
IP := Connection.Socket.Binding.PeerIP;
Nick := Connection.IOHandler.ReadLn;
if Nick <> ''
then
begin
Connection.IOHandler.WriteLn('Welcome ' + Nick + '!');
ListBoxClients.Items.Add(Nick);
end
else
begin
Connection.IOHandler.WriteLn('No Nick provided! Goodbye.');
Connection.Disconnect;
end;
end;
end;
procedure TForm2.tsExecute(AContext : TIdContext);
var
FMsg, FMSG2, FMSG3, msg, str, toname, filename, cmd, from,
orsender : string;
FStream, fstream2 : TFileStream;
MStream : TMemoryStream;
idx, posi, col : integer;
Name1, Name2, Name3, MainStr : string;
RXStreamRichedit, DictionaryMessageStream : TStringStream;
LStreamSize : int64;
begin
//Empty for test//
end;
procedure TForm2.tsDisconnect(AContext : TIdContext);
begin
AContext.Connection.Socket.InputBuffer.Clear;
AContext.Connection.Disconnect;
TLog.AddMsg(TMyContext(AContext).Nick + ' Left the chat');
ListBoxClients.Items.Delete
(ListBoxClients.Items.IndexOf(TMyContext(AContext).Nick));
end;
[편집]
문제는 ListBoxClients 함께 tsConnect 및 tsDisconnect에서. ThreadSafe를 만드는 방법을 찾고 있습니다.
사이드 노트 : 클래스와 해당 구현을 분리 된 파일로 저장하십시오! 코드가 더 읽기 쉬울 것입니다 –
이것은 전환하기에 너무 많은 코드입니다. 동일한 문제를 재현하는 [mcve]로 줄이십시오. 그러나'Active 'setter가 멈추는 가장 보편적 인 이유는 * 동기 * 동기화 작업 ('TThread.Synchronize()','TIdSync' 등)을 주 코드에 교착시키는 것입니다 스레드가 서버가 비활성화 될 때까지 기다리고 있습니다. * 비동기 * 동기화 작업 ('TThread.Queue()','TIdNotify' 등)을 사용하거나 작업자 스레드에서 서버를 비활성화하십시오. 서버 스레드가 주 스레드의 응답을 필요로하지 않는 한 * synchronous * syncs를 사용하지 마십시오. –
오늘 시도합니다. – benda