一个下载的窗体里就放一个进度条和一个下载按钮,下载的过程中(很慢)在窗口的任何地方点击一下,或做些其它的鼠标动作都会"没有响应"!(或者数据量小的话窗口处于假死状态)请大家帮忙!我自己搞不定啊!
主要代码很简单如下:
procedure IDHttp_Get(aURL: string);
var
  tStream: TFileStream;
  aFile : string;
begin
  aFile:=GetURLFileName(aURL);//GetURLFileName得到最后的url名字,如:http://localhost/aa/bb.exe,得到bb.exe
  if FileExists(aFile) then tStream := TFileStream.Create(aFile, fmOpenWrite)
  else tStream := TFileStream.Create(aFile, fmCreate);
  IdHTTP1.Request.ContentRangeStart := 0;
  try
    IdHTTP1.Get(aURL, tStream);
  finally
    tStream.Free;
  end;
end;procedure TUpdatefrm.sbn_startClick(Sender: TObject);
begin
  IDHttp_Get('http://50.50.50.50/aa/bb/cc.exe');
end;
关于ProgressBar的代码略去.
cc.exe的大小是2M,如果换成大约1M的文件的话,进度条只是走得快一些,但是如果点击窗体也一样会没有响应的状态,只有不动鼠标去点面结合,一直
等它下载完才没有不会出现窗体无法正常显示的假死状态.
我知道这与网速有关,因为我在内网测试的话进度条很快就过去了.但是给客户用的话不可能网速有这么快,请问我应该怎么办啊?在线...期待...

解决方案 »

  1.   

    然后TIdAntiFreeze设他的 Active 为 True , 就解决了问题的原因见TIdAntiFreeze组件的在线帮助Indy works on the blocking model. That is when calls are made to Indy the do not return until they are complete. If calls are made in the main thread this will cause the Application User Interface to "freeze" during Indy calls. TIdAntiFreeze counter acts this effect. TIdAntiFreeze allows Indy subsystem to make process Application message calls so that Windows messages continue to be executed while Indy blocking socket calls are in effect.
      

  2.   

    谢谢!不好意思,你说的那个问题我昨天就解决了(分我当然会给的!但还明问题,所有没结.).
    现在我想把原来的代码改成多线程的:procedure TThreadHttp.Execute;
    var
      tStream: TFileStream;
      aFile : string;
      IdHTTP1 : TIdHttp;
    begin
      FreeOnTerminate:=true;
      ......
      IdHTTP1:=TIdHTTP.Create(nil);
      ......
      IdHTTP1.Get(aURL, tStream);
      ......
    end;问题是原来的代码(如下):
    procedure IdHTTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
    begin
      ProgressBar1.Position:=ProgressBar1.Max;
    end;procedure IdHTTP1Status(ASender: TObject; const AStatus: TIdStatus;
      const AStatusText: String);
    begin
      Memo_Update.Lines.Add(AStatusText);
    end;
    用原来的会提示Undeclared identifier:'TWorkMode'等错误.应该怎么改啊?我放了进度条也要用啊!
      

  3.   

    >>示Undeclared identifier:'TWorkMode'等错误这个是编译错误,建议你把出现这个行错误的那句代码也贴出来,才好看原因;另外,如果你的procedure TThreadHttp.Execute;
    这些函数,的代码,跟IdHTTP1相关的代码,都贴出来,这样更好查问题
      

  4.   

    谢谢你们,我把我的代码都贴上来,希望你们帮忙一下!谢谢..
    线程单元主要代码如下:
    constructor TThreadHttp.create(myurl: string);
    begin
      inherited Create(false);
      aURL:=myurl;
    end;procedure TThreadHttp.Execute;
    var
      tStream: TFileStream;
      aFile : string;
      IdHTTP1 : TIdHttp;
    begin
      FreeOnTerminate:=true;
      IdHTTP1:=TIdHTTP.Create(nil);
      aFile:=GetURLFileName(aURL);//得到url最后一个文件名:如:如:http://localhost/aa/bb.exe,得到bb.exe
      if FileExists(aFile) then tStream := TFileStream.Create(aFile, fmOpenWrite)
      else tStream := TFileStream.Create(aFile, fmCreate);
      IdHTTP1.Request.ContentRangeStart := 0;
      try
        IdHTTP1.Get(aURL, tStream);
      except
        MessageBox(handle,PChar('请检查网络!'),'提示',MB_OK+MB_ICONINFORMATION);
        tStream.Free;
        IdHTTP1.Disconnect;
        Exit;
      end;
      tStream.Free;
      IdHTTP1.Disconnect;
    end;主窗体单元主要代码如下:
    procedure TUpdatefrm.sbnstartClick(Sender: TObject);
    var
     XMLDocument :IXMLDocument;
     XMLNode :IXMLNode;
     i,j:integer;
     Node_name:string;
     ThreadDown1: TThreadHttp;
    begin
      XMLDocument:=TXMLDocument.Create('http://aaa/aa/newversion.xml');
      XMLDocument.Active;
      XMLNode := XMLDocument.DocumentElement;
      j := XMLNode.ChildNodes.Count-1;
      for i:=0 to j do
      begin
        XMLNode := XMLDocument.DocumentElement;
        XMLNode:=XMLNode.ChildNodes.Nodes[i];
        if strtoint(XMLNode.Attributes['date'])>strtoint(nowversion_date) then //如果版本时间大于服务端的时间
        begin
          //Memo_Update.Lines.Add('即将下载数据:'+Node_name);
          Node_name:=XMLNode.NodeValue;
          ThreadDown1:=TThreadHttp.Create('http://aaa/aa/Down_Data/'+Node_name);
          //Memo_Update.Lines.Add('已成功下载!'+Node_name);
        end;
      end;
    end;主窗体里有个progressbar,在没有弄成多线程时的代码如下:
    procedure TUpdatefrm.IdHTTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
    begin
      ProgressBar1.Position:=ProgressBar1.Max;
    end;procedure TUpdatefrm.IdHTTP1Status(ASender: TObject;const AStatusText: String);
    begin
      Memo_Update.Lines.Add(AStatusText);
      Memo_Update.Lines.Add('正在下载数据,请耐心等待');
    end;procedure TUpdatefrm.IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCount: Integer);
    begin
      ProgressBar1.Position:=AWorkCount;
    end;   procedure TUpdatefrm.IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCountMax: Integer);
    begin
      ProgressBar1.Max:=AWorkCountMax;
      ProgressBar1.Min:=0;
      ProgressBar1.Position:=0;
    end;  改成了多线程后,我要把上面关于进度条的代码改一下用起来.应该怎么改?  
      

  5.   

    其中newversion.xml的文件如下:
    <version ver="5.5.5.5">
       <Item1 date="20061205">a.exe</Item1>   
       <Item2 date="20061205">b.xml</Item2> 
       <Item3 date="20061205">c.txt</Item3> 
    </version>
    上面的关于xml的代码我是循环得到a.exe,b.xml,c.txt
      

  6.   

    可以试试老冯在http://community.csdn.net/Expert/topic/5222/5222551.xml?temp=.4381983中说的方法可以上面你帖的代码中,这样改试试
    1.在线程单元 use  TUpdatefrm单元,这样TThreadHttp.Execute函数可以引用TUpdatefrm的事件处理理函数2.在TThreadHttp.Execute添加前面说的代码
      
      ...
      IdHTTP1:=TIdHTTP.Create(nil);  //加上这4句代码
      IdHTTP1.OnWorkBegin := Updatefrm.WorkBegin;
      IdHTTP1.OnWork := Updatefrm.Work;
      IdHTTP1.OnWorkEnd := Updatefrm.WorkEnd;
      IdHTTP1.OnStatus := Updatefrm.Status;
      
      aFile:=GetURLFileName(aURL);//得到url最后一个文件名...
      ... 这样样,要确保,TUpdatefrm这个窗口的实例名为Updatefrm,即在你的工程中有一个叫Updatefrm的窗口;
    最好在Updatefrm中放一个TIdAntiFreeze组件
      

  7.   

    谢谢do2008!可是不行,
    比如我就拿WorkEnd来做,在主窗体会提示:
    undeclared identified :'TWorkMode'
      

  8.   

    >>>undeclared identified :'TWorkMode'这个错误是没有将indy的源代码单元,添加到library path中,在IDE中,将$(DELPHI)\Source\Indy
    这个路径添加 到你的library path中即可