Multithreading 在不同线程中使用Overbytecs HTTP超时

Multithreading 在不同线程中使用Overbytecs HTTP超时,multithreading,delphi,http,timeout,delphi-xe,Multithreading,Delphi,Http,Timeout,Delphi Xe,我已经花了大约4天的时间试图找出这个错误。我正在使用Delphi XE,并创建了一个供翻译人员使用的小工具。我有了使用微软翻译API的想法,使事情变得更简单,少了一点繁琐 我创建了一个访问Microsoft translator API的类,但我想使其线程安全,以便可以在后台发出请求。我发送请求以获取访问令牌没有问题,但是,我在单独的线程中运行该请求。当用户单击一个按钮时,我生成一个新线程,并运行http请求从中翻译术语。但是,它每次都会超时。如果我从同一个线程运行它,就不会有问题 以下是我用于

我已经花了大约4天的时间试图找出这个错误。我正在使用Delphi XE,并创建了一个供翻译人员使用的小工具。我有了使用微软翻译API的想法,使事情变得更简单,少了一点繁琐

我创建了一个访问Microsoft translator API的类,但我想使其线程安全,以便可以在后台发出请求。我发送请求以获取访问令牌没有问题,但是,我在单独的线程中运行该请求。当用户单击一个按钮时,我生成一个新线程,并运行http请求从中翻译术语。但是,它每次都会超时。如果我从同一个线程运行它,就不会有问题

以下是我用于发送http请求的方法(传递的THttpCli对象在线程之间共享)

我想最明显的解决方案是让一个线程等待信号执行,但我希望得到一个关于超时发生原因的解释。我无法解释为什么第二个线程超时而第一个线程不超时

HTTP组件似乎卡在dnslookup上。Overbytecs使用Windows函数
WSAAsyncGetHostByName
查找名称

非常感谢您的帮助

2013年5月13日更新: 因此,事实证明,线程之间共享
THttpCli
对象似乎是导致超时的原因。解决方案就是将
nil
传递到上面我的函数中的
AHttpCli
参数中

我仍然会接受一个关于为什么会导致超时的答案。据我所知,
WSAAsyncGetHostByName
方法没有使用任何同步对象,并且另一个线程没有同时运行,因此不应该有任何东西阻塞线程

function sendHTTPRequest(APost: Boolean; AURI: UTF8string;
  AContentType: UTF8string; APostData: UTF8String; AHttpCli: TSSLHttpCli): UTF8string;
var
  DataOut: TMemoryStream;
  DataIn: TMemoryStream;
  lHTMLStream: TStringStream;
  lencoding: TUTF8Encoding;
  lownClient: boolean;
begin

  lownClient := false;
  if AHttpCli = nil then
  begin
    AHttpCli := TSSLHttpCli.Create(nil);
    AHttpCli.SslContext := TSSLContext.Create(nil);
    with AHttpCli.SslContext do
    begin
      SSLCipherList := 'ALL:!ADH:RC4+RSA:+SSLv2:@STRENGTH';
      SSLVersionMethod := sslV23_CLIENT;
      SSLVerifyPeerModes := [SslVerifyMode_PEER]
    end;
    AHttpCli.MultiThreaded := true;
    lownClient := true;
  end;

  AHttpCli.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';

  if APost then
  begin
    DataOut := TMemoryStream.Create;
    DataOut.Write(APostData[1], Length(APostData));
    DataOut.Seek(0, soFromBeginning);
  end;

  AHttpCli.URL := AURI;
  AHttpCli.ContentTypePost := AContentType;
  DataIn := TMemoryStream.Create;
  if APost then AHttpCli.SendStream := DataOut;
  AHttpCli.RcvdStream := DataIn;

  try
    if apost then
      AHttpCli.Post
    else
      AHttpCli.Get;

    lHTMLStream := TStringStream.Create('', TEncoding.UTF8);
    lHtmlStream.LoadFromStream(AHttpCli.RcvdStream);
    result := lHtmlStream.DataString;
    lHtmlStream.Free;

  finally
    AHttpCli.Close;
    AHttpCli.RcvdStream := nil;
    AHttpCli.SendStream := nil;
    DataIn.Free;

    if APost then
      DataOut.Free;

    if lownClient then
      AHttpCli.free;
  end;
end;