Закрытие клиентского потока изящно - PullRequest
4 голосов
/ 16 ноября 2011

Я устраняю неполадки клиента опроса Delphi 7 Indy9. Я попытался добавить TEvent с waitforsingleobject и многими другими способами изящного отключения. Ошибка происходит в readln. Обычно это ошибка «EIDConnection ... not connected». Я положил часы на него, и поток заканчивается. но 'while' не переоценивает условие до тех пор, пока соединение не получит сообщение от сервера, поэтому оно просто перебирает readln, пока не получит сообщение. Так что иногда он отключается изящно, но в большинстве случаев вылетает. Есть ли способ сделать это или я просто попробую ... кроме как вокруг чтения и продолжай ... заранее спасибо

procedure TReadingThread.Execute;
begin
    while not Terminated and FConn.Connected do
    begin
        // read msg from server
        Msg := FConn.ReadLn;
        Synchronize(ReceiveLine); 
    end;
end;

Ответы [ 2 ]

0 голосов
/ 16 ноября 2011

Я нашел ответ ... Readln будет ждать бесконечно, пока не получит возврат каретки.Таким образом, поток находится на Readln, пока сервер не отправит сообщение или сокет не будет отключен (что вызывает сбой).В коде компилятора Delphi в OnDisconnect был написан комментарий, чтобы перехватить ошибку с помощью try...except.Так что мне просто нужно быть осторожным, чтобы очистить перед отсоединением розетки.Я думал, что смогу найти более чистый метод закрытия.Спасибо за помощь.

0 голосов
/ 16 ноября 2011

Я думаю, вам нужно добавить некоторый код для обработки события Disconnect.У меня была проблема, аналогичная описанной вами, и вот что я сделал (в этом примере tcpServer является экземпляром TIdTCPServer):

    procedure TformRemoteControlWnd.tcpServerDisconnect(AContext: TIdContext);
    (*
    Connection is disconnected. Be careful, because this also gets called when
    the app is shutting down while a connection is active, in which case
    tcpServer may be gone already.
    *)
    begin
      if not Application.Terminated and Assigned(tcpServer) then
      begin
        sbarStatus.SimpleText := 'TCP/IP Disconnected';
        tcpServer.Tag := 0; // used to prevent rentrancy
      end;

      // shut down connection to stop thread from calling OnExecute event
      try
        AContext.Connection.Disconnect;
      except
        Sleep(0);
      end;
    end;
...