动态创建的控件在自己的事件中销毁自己安全吗?

myy 2005-11-14 03:10:51
我写了一个不可视控件,内部有个线程(用的是BeginThread,未用TThread),
线程函数的参数就是“Self”:

BeginThread(nil,0,@_WkrThreadProc,Pointer(Self),CREATE_SUSPENDED,dwThreadId);

另外控件有个私有的用AllocateHWnd()建立的隐藏窗口。


使用者调用控件的Start()方法后,Start()内启动线程,线程在工作中,不断用
PostMessage投递自定义的消息到隐藏窗口(线程退出前的最后一个消息是自定义
的WM_THREAD_END),隐藏窗口的窗口过程处理消息并调用事件点火代码触发事件,
WM_THREAD_END消息仅仅就是触发控件的OnEnd(Sender: TObject)事件,没有其他代码。

控件的destructor中先等待线程的结束(如果线程还在运行),清理一些成员,
然后DeallocateHWnd隐藏窗口,

-----------------------------
我的问题是:如果使用者动态创建控件,并在在控件的OnEnd事件里把控件自身销毁,
比如Sender.Free()是安全的吗?
...全文
151 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
aiirii 2005-11-14
  • 打赏
  • 举报
回复
重点是你释放的代码是如何处理的

另外,大多数情况都不建议直接 XXX..Destroy;
来释放,一般用close, free 之类的,然后,再“从容”释放
myy 2005-11-14
  • 打赏
  • 举报
回复
十分感谢各位的关注和建议。

其实我已经做过比较高强度的测试了(反复成批地大量创建控件实例,然后让其自己销毁,看有无错误,同时在任务管理器中观察内存、句柄等资源情况),暂时还没有发现什么问题,也许真的没有问题。

后来我仔细考虑了一下,发现问题最终归结到:
“在一个窗口的消息处理回调函数中销毁此窗口”这个问题上。

-------------------------------------------
>>控件的destructor中先等待线程的结束(如果线程还在运行),清理一些成员

>>是不是線程結後再執行destructor的其它的代碼呀.

不是,是这样:

destructor TMyComp.Destroy;
begin
//等待线程结束

//清理成员

Classes.DeallocateHWnd(_NotifyWnd);

inherited;
end;

tsst 2005-11-14
  • 打赏
  • 举报
回复
感觉上,VCL控件本身就存在自己释自己的现象的
不好意思,上面打错了!
tsst 2005-11-14
  • 打赏
  • 举报
回复
哇,高手如云啊
学习了!
还是想发表一下自己的意见,感觉上,VCL控件本身就存在自己释放看书的现象的
蒋晟 2005-11-14
  • 打赏
  • 举报
回复
Firing an event is like calling a method or function. So the event
handler is called from the object itself, which is still alive at that
time, and therefore it is potentially dangerous to delete it. It's OK to
delete if you are sure that the method where the event is fired from no
longer refers to any of the member variables (or resources). However, I strongly recommand the following alternative:

pIOleObject->Close(); //notify the object, so it can close itself gracefully
pIOleObject->Release();//free the object
konhon 2005-11-14
  • 打赏
  • 举报
回复
控件的destructor中先等待线程的结束(如果线程还在运行),清理一些成员

是不是線程結後再執行destructor的其它的代碼呀.
aiirii 2005-11-14
  • 打赏
  • 举报
回复
>>并在在控件的OnEnd事件里把控件自身销毁,
第一感觉没问题

其实你的 控件的OnEnd事件, 已经是在对应窗口的线程中调用,估计这里问题不大,
关键是你的destructor 中有否正确释放资源

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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