在不同线程中使用时的OverbyteICS HTTP超时

时间:2013-05-10 18:25:50

标签: multithreading delphi http timeout delphi-xe

我一直试图将这个错误弄清楚我们大约4天了。我正在使用Delphi XE并为翻译人员创建了一个小工具。我想到了使用Microsoft Translation API来帮助简化事情并且不那么繁琐。

我创建了一个访问Microsoft转换器API的类,但我想让它成为线程安全的,因此请求可以在后台进行。我发送获取访问令牌的请求没有问题,但是,我在一个单独的线程中运行该请求。当用户单击按钮时,我会生成一个新线程并运行http请求以从中转换术语。但是,它每次都会超时。如果我从同一个线程运行它没有问题。

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

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;

我认为显而易见的解决方案是只有一个线程等待信号执行,但我希望能够解释为什么超时发生。我无法解释为什么第二个线程超时而第一个没有。

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

非常感谢任何帮助

更新2013年5月13日:

因此,事实证明,在线程之间共享THttpCli对象似乎是导致超时的原因。解决方案只是将nil传递给我上面函数中的AHttpCli参数。

我仍会接受一个答案,说明为什么会导致超时。据我所知,WSAAsyncGetHostByName方法不使用任何同步对象而另一个线程没有同时运行,所以不应该阻塞线程。

0 个答案:

没有答案