为什么执行线程时,不能移动窗口或单击按钮???(100分)

  • 主题发起人 主题发起人 pzhiwyj
  • 开始时间 开始时间
P

pzhiwyj

Unregistered / Unconfirmed
GUEST, unregistred user!
我是初学者,请多多指教!为什么执行线程时,不能移动窗口或单击按钮???
 
线程同步(Synchronize)所致。
 
把你的代码贴出来看看,估计楼上说得有道理!
 
那是因为主线程被占用了,不要用Synchronize,执行关键任务
如果非要用,那么就是说没有使用线程的必要了
 
因为我需要在窗口上画线,所以用了Synchronize,就出现了以上情况,楼上的能不能说得仔细点啊!
 
你可以直接用API函数画线,可以支持多线程的,
或者在程序主线程中用定时器来画,
Synchronize是调用主线程来间接完成一些事情,线程处于等待状态,
而主线程则被占用,相当于没有使用多线程
 
LiChaoHui说的对,使用Synchronize时,就是使用主线程。
 
Delphi有个例子:
C:/Program Files/Borland/Delphi5/Demos/Threads/thrddemo.dpr
 
使用Synchronize时,倒也不是叫就是使用主线程,
只是主线程在等待
 
如果是循环,要加Application.ProcessMessages;
线程里用VCL时用Synchronize
 
以下是我对多线程的VCL的一点理解:
CPU只有一个(大多数是这样的)
显存也一样。
不管你怎么弄,都不会多出来的。
只是你的线程多了,系统就会多关照你一些。
 
要使界面不死,如果是单线程,可以在主线程中调用Application.ProcessMessages。如果子线程执行一个耗时操作(极端情况:一个死循环),则应该把子线程的优先级设低一些(如Idle优先级),也可以在线程的每次循环(线程体一般是个循环)里Sleep一下。
 
这个程序很能说明问题, 推荐给你:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
UseThread: TButton;
NoUseThread: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
function MyThreadFunc(P:pointer):Longint;stdcall;
var
i:integer;
DC:HDC;
S:string;
begin
DC:=GetDC(Form1.Handle);
for i:=0 to 100000do
begin
S:=Inttostr(i);
Textout(DC,10,10,Pchar(S),length(S));
end;
ReleaseDC(Form1.Handle,DC);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
hThread:Thandle;//定义一个句柄
ThreadID:DWord;
begin
//创建线程,同时线程函数被调用
hthread:=CreateThread(nil,0,@MyThreadfunc,nil,0,ThreadID);
if hThread=0 then
messagebox(Handle,'Didn’t Create a Thread',nil,MB_OK);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
MyThreadfunc(nil);
//没有创建线程时,直接调用线程函数
end;

end.

 
在线程里进行大量的计算和准备工作不会影响主线程(界面)的, 只有在画线的那一刻才应该使用Synchronize进行同步调用.你可以在Execute中这么写代码:
while not Terminateddo
// 可以在加上别的条件
begin
// 计算和处理数据
.....
.....
Synchronize(updateUI);
// 根据数据更新界面, 实际上如果是画线, 你可以先锁定花布, 然后画线, 然后释放花布, 也不一定要同步调用噢.
// 继续后面的处理
end
 
我在做一个图片、文字播放的软件,为了同步不得不用Synchronize(..),否则会出现,因为我这个软件是很多个区域播放不同的图片,所以有时会很慢,在Win2000下响应界面很慢。请问我该怎么办?
 
尽量让Synchronize()中过程中的处理轻量化。
如是一个繁重处理,可以把它分散Synchronize()。因Synchronize相当于把当前线程提升为主线程。
 
用缓冲区的办法。
1.用CreateCompatibleBitmap建一个缓冲区MemBitmap;
2.在线程中对MemBitmap进行操作;
3.操作完成后,由线程通知主线程更新到界面;
4.用消息通知可以最大程减少资源占用;
5.当然还可以采用加临界等手段防止对缓冲区的访问冲突.
6........
ok.
 
后退
顶部