多线程单元的主要代码如下:
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);
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
ThreadDown1: TThreadHttp;
begin
ThreadDown1:=TThreadHttp.Create('http://xxx/yy/a.txt');
Showmessage('下载成功!');
//CopyFile(ExtractFilePath + 'a.txt',ExtractFilePath+'bb\b.txt',false);
end;现在,我要问的问题是:
因为是多线程的,当我点击"下载"按钮执行到 ThreadDown1:=TThreadHttp.Create('http://xxx/yy/a.txt');
这句时,也就是程序正在下载时,比如a.txt有2M,程序还刚在下载过程中即只下载了1M的时候就执行下面的代码,
提示“下载成功”了。这时候文件还没有下载完全,所以不可能下载成功,更不可以执行我注释掉的那句(拷贝
下载完成的文件到指定的目录下)。
当我做成不是多线程的程序时,只要idhttp1.get(),程序会等到全部下载完成后再提示“下载成功!”,接着拷贝
文件也不会有问题了。
请问,我如果在多线程程序下得到文件下载完成这个状态,然后才提示“下载成功!”呢?在线等。。
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);
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
ThreadDown1: TThreadHttp;
begin
ThreadDown1:=TThreadHttp.Create('http://xxx/yy/a.txt');
Showmessage('下载成功!');
//CopyFile(ExtractFilePath + 'a.txt',ExtractFilePath+'bb\b.txt',false);
end;现在,我要问的问题是:
因为是多线程的,当我点击"下载"按钮执行到 ThreadDown1:=TThreadHttp.Create('http://xxx/yy/a.txt');
这句时,也就是程序正在下载时,比如a.txt有2M,程序还刚在下载过程中即只下载了1M的时候就执行下面的代码,
提示“下载成功”了。这时候文件还没有下载完全,所以不可能下载成功,更不可以执行我注释掉的那句(拷贝
下载完成的文件到指定的目录下)。
当我做成不是多线程的程序时,只要idhttp1.get(),程序会等到全部下载完成后再提示“下载成功!”,接着拷贝
文件也不会有问题了。
请问,我如果在多线程程序下得到文件下载完成这个状态,然后才提示“下载成功!”呢?在线等。。
Showmessage('下载成功!'); =============================
其实这个代码是顺序执行的,线程创建后,showmessage就执行了。
并不是等你下载完了才执行后面的语句。
下载动作是在线程中执行的。你可以在线程中向主线程PostMessage,告知任务完成。自定义一个消息:
WM_SUCCED = WM_USER + 1;
procedure TThreadHttp.Execute;
var
... tStream.Free;
IdHTTP1.Disconnect;
PostMessage(FrmMain.Handle, WM_SUCCED, 0, 0);
end;窗体中定义处理此消息的过程:
procedure ProcessSucessed(var message:TMessage);message WM_SUCCED;
procedure TFrmMain.ProcessSucessed(var Message: TMessage);
begin
Showmessage('下载成功!');
end;
其实我下载的文件不只一个,比如有三个,我写在xml里,
其余的代码不变,“下载”按钮的代码去循环读xml里的文件名下载,如下:
procedure TUpdatefrm.sbnstartClick(Sender: TObject);
var
XMLDocument :IXMLDocument;
XMLNode :IXMLNode;
Node_name:string;
begin
XMLDocument:=TXMLDocument.Create(xmldir+'/aa/a.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(nowverdate) then //比较时间
begin
Node_name:=XMLNode.NodeValue;
ThreadDown1:=TThreadHttp.Create(xmldir+'/bb/'+Node_name); //创建下载线程
end;
end;
end;
按照YouToBe的方法我已经解决了一个文件下载结束的问题,如果像上面一样有多个文件在xml里要下载,就会有几个文件下载就弹出几个“下载成功”。
请问怎么判断最后一个文件下载完成?
我本来以为当i=j的时候执行完:
procedure TUpdatefrm.ProcessSucessed(var Message: TMessage);
begin
if i=j then
Showmessage('下载成功!');
end;但是好像行不通。请大家帮忙了。。
var
iTotal: integer;//总文件数
iSucced:integer;//成功个数先在sbnstartClick过程中取得总文件数量,赋值给iTotal并且iSucced初始化为0;
iTotal := ?
iSucced:= 0;然后:procedure TUpdatefrm.ProcessSucessed(var Message: TMessage);
begin
Inc(iSucced);
if iSucced = iTotal then
Showmessage('下载成功!');
end;
iSucced:= 0;在你创建下载线程之前进行赋值