我用多线程调用API, 在线程的Execute中使用了同步Synchronize,问题是在线程执行的时候程序像死机一样没有反应,界面上的任何东西都无法使用,去掉Execute中的同步又恢复正常(虽可使用但是有时无法正常下载),请问怎么解决?type
ThttpdownThread = class(TThread)
private
{ Private declarations }
procedure httpdown;
protected
procedure Execute; override;
end;procedure ThttpdownThread.Execute;
begin
Synchronize(httpdown);
end;procedure thttpdownthread.httpdown;
begin
//下载代码,其中使用了VCL
end;
ThttpdownThread = class(TThread)
private
{ Private declarations }
procedure httpdown;
protected
procedure Execute; override;
end;procedure ThttpdownThread.Execute;
begin
Synchronize(httpdown);
end;procedure thttpdownthread.httpdown;
begin
//下载代码,其中使用了VCL
end;
procedure ThttpdownThread.Execute;
begin
httpdown;
end;procedure thttpdownthread.httpdown;
begin
//下载代码,其中使用了VCL
.....
Synchronize(refreshForm1Memo);
.....
end;
修改memo的文字也是不行的
我的理解是访问其他的类的过程的函数的时候需要线程的同步才用这个函数的 不知道自己理解的对不对?
如果你把你个需要耗费很多CPU时间的东西用Synchronize
同步了,那你的主线程就会因为忙着别的东西而没有时间更
新界面了,换句话说你的程序就和单线程没什么区别了。
procedure ThttpdownThread.Execute;
begin
Synchronize(httpdown);
end;
你一开始就把线程要做的东西都压进了主线程,你这样的程序
和单线程程序是一样的。你应该在ThttpdownThread.Execute;
里面多写点东西,只是必须更新界面的代码写在ThttpdownThread.Getout
里面就行了。
具体的,我不想多说,你就按照这个思路更改你的程序即可。
应尽量减少Synchronize的使用。用多了你的程序就和单线程一样了。还有,记得给分。angle097113(深思不解)
outer2000(天外流星) 说的都是正确的。
如果不用, ThttpdownThread这个线程刚开始执行的时候就会造成假死,界面上的任何东西都没办法点,标题栏也会变成白色。我只想解决使用Synchronize 怎么能不假死,是不是我创建多线程的方法有问题?
1,用到VCL都在THREAD里CREATE后使用;当然要注意释放了,呵呵
2,这样你就没必要用SYNCH方法了,如果一定要给MEMO什么的加东西,可以单独写
一个SYNCH方法;我想不会影响的
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, wininet, StdCtrls, inetutil, Menus; type
TFtpconnThread = class(TThread)
private
{ Private declarations }
procedure ftpconn;
protected
procedure Execute; override;
end;type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
Edit3: TEdit;
Memo1: TMemo;
MainMenu1: TMainMenu;
a: TMenuItem;
a1: TMenuItem;
b: TMenuItem;
b1: TMenuItem;
c: TMenuItem;
c1: TMenuItem;
asdasdasd1: TMenuItem;
adsasdsda1: TMenuItem;
sddsasd1: TMenuItem;
asdsdasd1: TMenuItem;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
hi, fi : HINTERNET;
end;var
Form1: TForm1;implementation{$R *.dfm}procedure tftpconnthread.Execute;
begin
Synchronize(ftpconn);
end;procedure tftpconnthread.ftpconn;
begin
form1.hi := InternetOpen('VCS FTP', INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0);
connCheck(LongBool(form1.hi));
form1.fi := InternetConnect(form1.hi, PChar(form1.edit1.text),21,
PChar(form1.Edit2.Text), PChar(form1.Edit3.Text), INTERNET_SERVICE_FTP, 0, 0);
connCheck(LongBool(form1.fi));
end;procedure TForm1.Button1Click(Sender: TObject);
var
test1:tftpconnthread;
begin
test1:=tftpconnthread.Create(true);
test1.Resume;
end;end.连接检查代码
unit INetUtil;interfaceuses SysUtils, Classes, Windows, WinINet; procedure connCheck(b: LongBool);implementationuses Unit1,Forms, Controls;
procedure connCheck(b: LongBool);
var
TmpErr2 : DWORD;
Len2 : DWORD;
Buf2 : array[0..max_path] of char;
begin
Len2 := sizeof(Buf2);
InternetGetLastResponseInfo(TmpErr2, Buf2, Len2);
Buf2[Len2] := #0;
if buf2<>'' then
form1.memo1.lines.Add(buf2);
end;
end.
各位可以试试连接一个ftp服务器,点击连接(button1)后,窗体1上的Mainmenu就不能点了,一直到连接完毕。
单独写一个METHOD;就是ADD一条到MEMO里;这个方法 SYN;procedure tftpconnthread.Execute;
begin
CHECK;
ftpconn;
//ADD MEMO ITEM;USE SYN。。
end;