Multithreading 在不同线程中使用Overbytecs HTTP超时
我已经花了大约4天的时间试图找出这个错误。我正在使用Delphi XE,并创建了一个供翻译人员使用的小工具。我有了使用微软翻译API的想法,使事情变得更简单,少了一点繁琐 我创建了一个访问Microsoft translator API的类,但我想使其线程安全,以便可以在后台发出请求。我发送请求以获取访问令牌没有问题,但是,我在单独的线程中运行该请求。当用户单击一个按钮时,我生成一个新线程,并运行http请求从中翻译术语。但是,它每次都会超时。如果我从同一个线程运行它,就不会有问题 以下是我用于发送http请求的方法(传递的THttpCli对象在线程之间共享) 我想最明显的解决方案是让一个线程等待信号执行,但我希望得到一个关于超时发生原因的解释。我无法解释为什么第二个线程超时而第一个线程不超时 HTTP组件似乎卡在dnslookup上。Overbytecs使用Windows函数Multithreading 在不同线程中使用Overbytecs HTTP超时,multithreading,delphi,http,timeout,delphi-xe,Multithreading,Delphi,Http,Timeout,Delphi Xe,我已经花了大约4天的时间试图找出这个错误。我正在使用Delphi XE,并创建了一个供翻译人员使用的小工具。我有了使用微软翻译API的想法,使事情变得更简单,少了一点繁琐 我创建了一个访问Microsoft translator API的类,但我想使其线程安全,以便可以在后台发出请求。我发送请求以获取访问令牌没有问题,但是,我在单独的线程中运行该请求。当用户单击一个按钮时,我生成一个新线程,并运行http请求从中翻译术语。但是,它每次都会超时。如果我从同一个线程运行它,就不会有问题 以下是我用于
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;