TTestThread = class(TThread)
  public
    httpMain: TIdHTTP;
    sslMain: TIdSSLIOHandlerSocketOpenSSL;
    constructor Create; overload;
    destructor Destroy; override;
    procedure Execute; override;
  end;constructor TTestThread.Create;
begin
  inherited Create(False);
  httpMain := TIdHTTP.Create(nil);
  sslMain  := TIdSSLIOHandlerSocketOpenSSL.Create(nil);  sslMain.SSLOptions.Method := sslvSSLv3;
  sslMain.SSLOptions.Mode := sslmUnassigned;
  httpMain.AllowCookies := True;
  httpMain.HandleRedirects := True;
  httpMain.HTTPOptions := [hoKeepOrigProtocol, hoForceEncodeParams];
  httpMain.ReadTimeout := 20000;
  httpMain.ConnectTimeout := 10000;
end;destructor TTestThread.Destroy;
begin
  httpMain.Free;
  sslMain.Free;
  inherited Destroy;
end;procedure TTestThread.Execute;
begin
  while not Terminated do begin
    httpMain.IOHandler := sslMain;
    httpMain.Request.UserAgent := 'Mozilla/3.0 (compatible)';
    httpMain.Get('https://mail.qq.com/cgi-bin/loginpage?');
  end;  Destroy;
end;如果我创建并执行50个线程(上面的代码),过一段时间会出现“Socket Error # 10038 Socket operation on non-socket.”。
如果出现了这个异常,这个 idhttp 将会彻底失效,get 将永远是“不能访问内存 000004” 什么的。
请问我应该如何避免这个异常(虽然上面的代码不容易出错,但如果使用代理连接,10038 异常会非常非常多)。单线程执行上述代码永远不会出现 10038,即便使用代理连接。各位大大们,指点我一下吧。

解决方案 »

  1.   

    4个地方问题
    1、 inherited Create(False); 这个执行后,线程已经开始运行,但是你idhttp对象可能还未创建。
    所以应该改成inherited Create(True); 然后在构造函数末尾加上Resume;2、这个httpMain.Get('https://mail.qq.com/cgi-bin/loginpage?');应该加上try...except,因为会产生异常,导致线程挂掉。3、这部分代码    httpMain.IOHandler := sslMain;
        httpMain.Request.UserAgent := 'Mozilla/3.0 (compatible)';建议放入构造函数中,无需重复执行。4、线程函数末尾不该调用Destroy,释放可以在构造函数中将 FreeOnTerminate 设置为True
      

  2.   

     idhttp 是什么版本?
     idhttp的旧版本好像有问题 用新版