几年前做的一个项目了,最近维护。需要程序每隔5秒左右查询一次WEB网页,并分析其中数据。
我做了一个线程类,在线程里(只有一个线程,放到线程里怕下载网页的过程影响用户界面操作)下载网页-》解析内容-》休眠-》下载网页,如此反复。
现在碰到一个非常严重的问题,HTTP下载的时候,在我的I3 CPU上,CPU占用率为23%左右,而在那些赛扬级别的用户电脑上,这个过程CPU占用率达到70%以上,这简直是场灾难!用户看个视频都不连贯。
这几天尝试换过很多HTTP组件,包括indy的tidhttp,ICS的thttpcli;也尝试过直接调用wininet或者winsock,CPU占用率都是居高不下。
今天怀疑是在线程里工作出现的问题,于是将HTTP下载代码用一个timer组件调用,问题依旧。不知道各位有没有碰到过类似情况,有没有解决办法。对了,异步方式、线程里SLEEP等等都试过了,没有效果。而且通过调试,可以确定就是HTTP GET的时候CPU占用率偏高。

解决方案 »

  1.   

    indyhttp是阻塞式的,使劲读,有结果才罢休,你可以放置一个IdAntiFreeze1组件,在indy misc页签下,据说可以反阻塞
      

  2.   

    谢谢楼上,我试过,没用。我现在的情况应该不像阻塞引起的。因为我用THTTPCLI的GetAsync,一样没有效果。如果直接用tidhttp,不做任何处理,CPU占用更高。
      

  3.   

    有那么严重吗,我这单进程中循环Get,cpu都没有多少
      

  4.   

    貌似不在线程里GET情况还好点。
      

  5.   

    下面是我在线程里HTTP GET的函数function TGetInfo.HttpGet(const Url: string; var Html: string; bgziped:Boolean=False): Boolean;
    var
      DataLen: Int64;
      destStream:TMemoryStream;
      Tick:Cardinal;
    begin
      Result := False;
      FHttp.URL := Url;
      //HttpClient.NoCache := True;
      Tick := GetTickCount;
      destStream := TMemoryStream.Create;
      FHttp.RcvdStream := TMemoryStream.Create;
      try
        try
          FHttp.GetAsync;      while FHttp.State <> httpReady do
          begin
            if GetTickCount - Tick > 10*1000 then  //超时10S
            begin
              FHttp.Abort;
              Exit;
            end;
            Sleep(20);
          end;      FHttp.RcvdStream.Position := 0;
          //datalen := FHttp.RcvdStream.Size;
          //SetLength(Html, datalen);
          //FHttp.RcvdStream.Read(PChar(Html)^, DataLen);
          if(bgziped) then
            zlibex.ZDecompressStream(FHttp.RcvdStream,destStream);
          DataLen := destStream.Size;
          SetLength(Html, DataLen);
          destStream.Position := 0;
          destStream.Read(PChar(Html)^, DataLen);
          Result := True;
        except    end;
      finally
        destStream.Free;
        FHttp.RcvdStream.Free;
        FHttp.RcvdStream := nil;
      end;
    end;
      

  6.   

    试试放到线程里get,主线程循环等待结果吧。