在线程下画图的问题(100分)

  • 主题发起人 主题发起人 lxddd
  • 开始时间 开始时间
L

lxddd

Unregistered / Unconfirmed
GUEST, unregistred user!
一个线程画图的程序,如果不运行其它程序始终正常。运行后再执行其它程序,过一
段时间就出问题:PaintBox1的画面不再更新,快则5分钟慢到4小时。画图代码如果用
定时器实现也始终正常。另外98比2000更易出问题。
procedure MyThread.Execute;
var Bmp:TBitmap;
begin
Bmp:=TBitmap.Create;
Bmp.Width:=form1.PaintBox1.Width;
Bmp.Height:=form1.PaintBox1.Height;
Bmp.PixelFormat:=pf16bit;
repeat
Bmp.Canvas.Lock;
form1.PaintBox1.Canvas.Lock;
Bmp.Canvas.FillRect(Rect(0,0,200,200));
Bmp.Canvas.MoveTo(Random(200),Random(200));
Bmp.Canvas.LineTo(Random(200),Random(200));
form1.PaintBox1.Canvas.Draw(0,0,Bmp);
form1.PaintBox1.Canvas.Unlock;
Bmp.Canvas.Unlock;
Sleep(200);
until Terminated;
Bmp.Free;
end;

各位高手,到底哪儿出了问题啊?
 
是线程安全问题,线程中调用VCL控件必须用Synchronize()同步
 
procedure MYthread.test;
var Bmp:TBitmap;
begin
Bmp:=TBitmap.Create;
Bmp.Width:=form1.PaintBox1.Width;
Bmp.Height:=form1.PaintBox1.Height;
Bmp.PixelFormat:=pf16bit;
repeat
Bmp.Canvas.Lock;
form1.PaintBox1.Canvas.Lock;
Bmp.Canvas.FillRect(Rect(0,0,200,200));
Bmp.Canvas.MoveTo(Random(200),Random(200));
Bmp.Canvas.LineTo(Random(200),Random(200));
form1.PaintBox1.Canvas.Draw(0,0,Bmp);
form1.PaintBox1.Canvas.Unlock;
Bmp.Canvas.Unlock;
Bmp.Free;
end;

procedure MyThread.Execute;
Synchronize(test);
end;
 
说说原因
delphi4中的vcl不是线程安全的。
(注意,如果你试着从线程中调用VCL的可视元素,你的系统肯定是迟早要崩溃的,
但是,崩溃也许不会立即发生。)
为了避免出现这种情况,只有采取一种叫做TThread对象的折衷方法。
1。它提供了Synchronize函数,是你能够从一个线程调用vcl.
2。它提供了线程局部存储器(thread locaol storage)的一个替代物,使运行速度可以快10倍。
作为一般性的规则,你能在一个线程莉调用vcl的唯一方式就是适用synchronize。
关键是几乎大部分的vcl不是线程安全的,所以当程序在一个线程中的时候,你不能访问vcl。
周期,就是它的原因。调用synchronize实际上就是暂时结束你的线程,并使它成为你的应用程序
的主线程的一部分。这段时间内,你可以调用vcl。在你已完成对vcl的访问的时候,就应该中断程
序中同步完成部分的代码。
 
或者用其他的一些API来代替,比如POSTMESSAGE等
 
晕,刚才没看清楚,你已经用了Lock,UnLock来保证线程的安全,应该不是线程安全的问题了
能把问题说具体点吗?
 
我也觉得奇怪
 
  是啊,我也觉得奇怪。
  最怪的是bmp这个局部变量,明明不会有其它线程访问,但如果不Lock,
肯定会出事,而且很快。
  如果用Synchronize,那其实就是在主线程里运行,也用不着再开一个
线程了。
  Windows API是不是线程安全的?如果是,可以考虑。
  还有什么办法用线程在窗体上画图呢?
 
楼上的兄弟,我用Lock的方式做的test,运行5个多小时了,没什么问题呀,是不是别的什么地方有问题呀?
 
我是这样测试的:运行它,然后照常做其它事,上网、QQ、联众游戏、Delphi,中间不时
地把此程序最小化、恢复、拖动,最快的一次是在笔记本的98环境,5分钟就出事,最
慢的一次是在2000里,只玩拖拉机,坚持了4个小时。
 
你的资源可能没有释放干净,我记的DFW以前有好几个类似的帖子, 找来看看把[8D]
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
442
import
I
I
回复
0
查看
771
import
I
I
回复
0
查看
641
import
I
后退
顶部