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

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调用。可是出错。不下载文件,请教大家我哪里错了。谢谢
...全文
141 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
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
  • 打赏
  • 举报
回复
出错信息是什么,如果只是下载不下来,那就有可能是其他问题,比如网络问题

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧