关于用indyhttp下载的请教:(50分)

  • 主题发起人 主题发起人 newmoonfaw
  • 开始时间 开始时间
N

newmoonfaw

Unregistered / Unconfirmed
GUEST, unregistred user!
刚试着学多线程,想用indy做下载,但在下载过程中用户界面还是没响应,直到下载完毕才响应,不知道哪里错了。程序简单内容如下:

unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
IdHTTP;
type
TDownloadThread=class(TThread)
private
Answer:integer;
Protected
Proceduredo
wnload;
Procedure Execute;Override;
end;

TMainForm = class(TForm)
Memo1: TMemo;
Label1: TLabel;
Edit1: TEdit;
Button1: TButton;
Label2: TLabel;
Edit2: TEdit;
Button2: TButton;
IdHTTP1: TIdHTTP;
sdlg: TSaveDialog;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
MainForm: TMainForm;
implementation
{$R *.DFM}
procedure TMainForm.Button1Click(Sender: TObject);
var NewThread:TDownloadThread;
begin
NewThread:=TDownloadThread.create(False);
end;

Procedure TDownloadThread.Download ;
var tmpStream:TFileStream;
begin
with MainFormdo
begin
try
idhttp1.Get(Edit1.Text,tmpStream);
finally
tmpStream.Free;
end;
end;

end;

Procedure TDownloadThread.Execute;
begin
FreeOnTerminate:=true;
Synchronize(Download);
end;

end.
 
Procedure TDownloadThread.Download ;
var tmpStream:TFileStream;
begin
tmpStream:=TFileStream.Create('your file path',fmCreate);
//如果指定路径的文件不存在用fmCreate否则用fmOpenReadWrite
with MainFormdo
begin
try
idhttp1.Get(Edit1.Text,tmpStream);
finally
tmpStream.Free;
end;
end;
end;
.....
》》Synchronize(Download);
这里觉得没必要用Synchronize,去掉试试
 
好,我试试。
 
to ZRWeng:请问为什么去掉了Synchronize就好用了?
 
Synchronize通过它可以让线程的一些方法在主线程中执行。
如,在附属线程中操作的界面显示下载进度等,要通过Synchronize方法
 
那么如果在我的线程TDownloadThread里面有showmessage等行为时,它应该算是在主线程中执行的吧?
如果还有打开对话框操作的呢?
 
to ZRWeng:如果我要把下载的文件的文件名存为打开对话框TSaveDialog的Filename时,为了保持同步,是否就得用Synchronize了?如果是这样的话,那主界面仍旧会停止响应啊?
 
什么意思?你该不会在执行线程的时候打开SaveDialog吧,
其实你可以在主程序中pause线程的执行,当另存后在 Resume执行线程
 
我的意思是说,在执行一个线程把文件保存为Tsavedialog.filename时,可能又执行了一个下载的线程,这时前一个线程还未结束,后一个线程就把Tsavedialog.filename属性修改了。
 
多线程访问同一个方法或变量,最好设定一个临界量或互斥变量
如;
var
Lock:TTCriticalsection;
begin

Lock:=TCriticalsection.Create;
Lock.Enter;
//访问Tsavedialog.filename操作
Lock.Leave;
。。。
 
谢谢ZRWeng,我先练练,等有不会的再继续向您请教,分数不多,先收下。
 

Similar threads

后退
顶部