一个下载的窗体里就放一个进度条和一个下载按钮,下载的过程中(很慢)在窗口的任何地方点击一下,或做些其它的鼠标动作都会"没有响应"!(或者数据量小的话窗口处于假死状态)请大家帮忙!我自己搞不定啊!
主要代码很简单如下:
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的文件的话,进度条只是走得快一些,但是如果点击窗体也一样会没有响应的状态,只有不动鼠标去点面结合,一直
等它下载完才没有不会出现窗体无法正常显示的假死状态.
我知道这与网速有关,因为我在内网测试的话进度条很快就过去了.但是给客户用的话不可能网速有这么快,请问我应该怎么办啊?在线...期待...
主要代码很简单如下:
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的文件的话,进度条只是走得快一些,但是如果点击窗体也一样会没有响应的状态,只有不动鼠标去点面结合,一直
等它下载完才没有不会出现窗体无法正常显示的假死状态.
我知道这与网速有关,因为我在内网测试的话进度条很快就过去了.但是给客户用的话不可能网速有这么快,请问我应该怎么办啊?在线...期待...
现在我想把原来的代码改成多线程的: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'等错误.应该怎么改啊?我放了进度条也要用啊!
这些函数,的代码,跟IdHTTP1相关的代码,都贴出来,这样更好查问题
线程单元主要代码如下:
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; 改成了多线程后,我要把上面关于进度条的代码改一下用起来.应该怎么改?
<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
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组件
比如我就拿WorkEnd来做,在主窗体会提示:
undeclared identified :'TWorkMode'
这个路径添加 到你的library path中即可