第一次采用多线程编程,碰到问题,请教下大家

messah 2010-02-09 04:14:19
unit Unit2;

interface

uses
Classes,Registry;

type
download = class(TThread)
private
{ Private declarations }
public
constructor create;
protected
procedure Execute; override;


end;

implementation
uses Unit1;

{
Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,

Synchronize(UpdateCaption);

and UpdateCaption could look like,

procedure download.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;

or

Synchronize(
procedure
begin
Form1.Caption := 'Updated in thread via an anonymous method'
end
)
);

where an anonymous method is passed.

Similarly, the developer can call the Queue method with similar parameters as
above, instead passing another TThread class as the first parameter, putting
the calling thread in a queue with the other thread.

}

{ download }

constructor download.create;
begin
inherited Create(True);
end;


procedure download.Execute;
var savefilestream:TFilestream;
Reg:TRegistry;
begin
try
Form1.Timer1.Enabled:=False;
SaveFileStream := TFileStream.Create('tmp.exe',fmCreate);
Form1.idhttp1.Create(nil);
Form1.idhttp1.Request.URL:=Form1.url;
Form1.idhttp1.Connected;
Form1.idhttp1.Get(Form1.url,SaveFileStream);
SaveFileStream.Free;
except
Form1.Close;
end;
{ Place thread code here }
end;

end.

线程代码如上,在主程序中用download.create调用。可是出错。不下载文件,请教大家我哪里错了。谢谢
...全文
109 点赞 收藏 12
写回复
12 条回复
mynameis_007 2010年02月11日
constructor download.create;
begin
inherited Create(True);
end;
将此改成
inherited Create(Suspended);
FreeOnTerminate := true;

线程内不要用Form1.Close,你返回ModalResult就ok

用Form1.ModalResult := mrOK;
回复 点赞
wxieyang 2010年02月11日
在子线程中如果不采用线程同步技术,不能直接操纵主线程中的VCL对象,因为VCL对象不是线程安全的,你不遵循这个规则,就可能会出现莫名其妙的错误。
你可以把
try
Form1.Timer1.Enabled:=False;
SaveFileStream := TFileStream.Create('tmp.exe',fmCreate);
Form1.idhttp1.Create(nil);
Form1.idhttp1.Request.URL:=Form1.url;
Form1.idhttp1.Connected;
Form1.idhttp1.Get(Form1.url,SaveFileStream);
SaveFileStream.Free;
except
Form1.Close;

这段代码放入一个函数中,并在线程中以 Synchronize 的方式调用这个函数。
但是这样实际上下载过程是在主线程中进行了,这就失去了线程的意义。

如果你一定要在线程中实现下载,那么你可以在线程中动态创建下载用的控件 idhttp ,
线程中下载完成之后,通过 Synchronize 的方式将下载之后的数据显示在主线程中。
(不过,看你的程序,好像不需要将数据显示在主线程中,只需要在完成下载之后通知下主线程就可以了)

回复 点赞
ZyxIp 2010年02月10日
有一个使用线程的例子。
http://blog.csdn.net/ZyxIp/archive/2010/02/10/5304433.aspx

回复 点赞
messah 2010年02月10日
跟不到哪里出错啊。文件夹权限也是正常的。如果不放线程里,直接放主程序里,这个过程完全正常。但是因为放主程序里的话,一旦开始下载,程序就是假死的现象。切换出去的话再切换回来就看不到了。必须要等东西下完才行。
回复 点赞
Storm2008 2010年02月10日
Form1.idhttp1.Create(nil); 
Form1.idhttp1.Request.URL:=Form1.url;
Form1.idhttp1.Connected;
Form1.idhttp1.Get(Form1.url,SaveFileStream);


是不是应该改成
XX := Form1.idhttp1.Create(nil);
XX.XX := XXX

纯猜测
回复 点赞
dd_zhouqian 2010年02月10日
太乱,Form1.Close; 为啥要放到线程里去做,直接发个消息好了
还有你这个只是个任务,只执行了一次,有必要用线程吗
回复 点赞
ezhuo 2010年02月10日
你没有用Synchronize,是会容易异常的,在执行线程外的对象的时要用Synchronize
回复 点赞
diruser 2010年02月10日
Execute中的代码要放在Synchronize中调用
回复 点赞
zshsuming 2010年02月09日
下载的文件或者文件夹,是否有everyone,完全控制权限?
回复 点赞
bdmh 2010年02月09日
那你就跟一下,看看哪里是否为nil了
回复 点赞
messah 2010年02月09日
出错信息直接就是一个非法操作的错误啊
回复 点赞
bdmh 2010年02月09日
出错信息是什么,如果只是下载不下来,那就有可能是其他问题,比如网络问题
回复 点赞
发动态
发帖子
语言基础/算法/系统设计
创建于2007-08-02

3420

社区成员

3.3w+

社区内容

Delphi 语言基础/算法/系统设计
社区公告
暂无公告