0

GET我正在我的 deplhi 项目中实现实时聊天,它通过向服务器发出请求来接收新消息。如果没有新消息出现,服务器本身会在 20 秒后关闭连接。上面描述的代码位于一个单独的线程中(它是在访问聊天“页面”时创建的),因此它不会冻结 GUI。当我从聊天转到非聊天页面时,我在外部调用此代码thread_chat以使线程退出:

if thread_chat <> nil then
begin
  thread_chat.Terminate;
  thread_chat := nil;
end;

但是,由于我的服务器超时为 20 秒,因此线程实际上仅在收到响应时才关闭(是的,这听起来合乎逻辑,因为我的线程循环是while not Terminated do)。所以我正在寻找的是在请求中间关闭 HTTP 连接。

尝试#1

最初我TerminateThread通过称它为

TerminateThread(thread_chat.Handle, 0)

这工作正常,直到我第二次尝试杀死线程 - 我的应用程序完全冻结。所以我去了

尝试#2

我创建了一个全局变量URL_HTTP: TIdHTTP,并使用此函数接收服务器页面内容:

function get_URL_Content(const Url: string): string;
var URL_stream: TStringStream;
begin
  URL_HTTP := TIdHTTP.Create(nil);
  URL_stream := TStringStream.Create(Result);
  URL_HTTP.Get(Url, URL_stream);
  if URL_HTTP <> nil then
  try
    URL_stream.Position := 0;
    Result := URL_stream.ReadString(URL_stream.Size);
  finally
    FreeAndNil(URL_HTTP);
    FreeAndNil(URL_stream);
  end;
end;

当我在外面调用这段代码时thread_chat

if thread_chat <> nil then
begin
  URL_HTTP.Disconnect;
  thread_chat.Terminate;
end;

我得到EidClosedSocket了异常(在写这篇文章时经过一些测试,我得到了EAccessViolation错误)。

我没有主意了。如何在服务器响应之前关闭 HTTP 请求?


procedure thread_chat.Execute;  //overrided
begin
    while not Terminated do
      if check_messages then  //sends request to the server, processes response, true if new message(s) exist
        show_messages;
end;
4

1 回答 1

1

尝试这样的事情:

type
  TThreadChat = class(TThread)
  private
    HTTP: TIdHTTP;
    function CheckMessages: Boolean;
    procedure ShowMessages;
  protected
    procedure Execute; override;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Stop;
  end;

constructor TThreadChat.Create;
begin
  inherited Create(False);
  HTTP := TIdHTTP.Create(nil);
end;

destructor TThreadChat.Destroy;
begin
  HTTP.Free;
  inherited;
end;

function TThreadChat.CheckMessages: Boolean;
var
  Resp: string;
begin
  //...
  Resp := HTTP.Get(Url);
  //...
end;

procedure TThreadChat.ShowMessages;
begin
  //...
end;

procedure TThreadChat.Execute;
begin
  while not Terminated do
  begin
    if CheckMessages then
       ShowMessages;
  end;
end;

procedure TThreadChat.Stop;
begin
  Terminate;
  try
    HTTP.Disconnect;
  except
  end;
end;

thread_chat := TThreadChat.Create;

...

if thread_chat <> nil then
begin
  thread_chat.Stop;
  thread_chat.WaitFor;
  FreeAndNil(thread_chat);
end;
于 2015-06-01T21:27:51.057 回答