Delphi 表单创建无需冻结主线程
我想做的事情遇到了麻烦。 我有一些大的表格需要一些时间来创建。 为了使应用程序加载速度更快,我想到让表单在主表单的 OnCreate 事件中创建的线程中创建。 该线程有一个 TApplication 类型的 FApplication 字段,这显然是 Application 变量。 我用它在线程上创建表单,但即使我尝试了
FApplication.CreateForm (TfrmXXX, frmXXX)
,
frmXXX := TFrmXXX.Create(FApplication)
表单仍然没有创建。 有什么解决方法吗?
提前致谢。
I am having trouble with something i wanna do. I have some big forms which take some time to create. To make the app load faster i thought of letting the forms be created in a thread which is created at main form's OnCreate event. The thread has a FApplication field of type TApplication which obviously is the Application variable. I use that to create the forms on the thread, but even tho I tried
FApplication.CreateForm (TfrmXXX, frmXXX)
and
frmXXX := TFrmXXX.Create(FApplication)
the forms still arent created. Is there any workaround for this ?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
在线程中创建表单根本行不通。 VCL,尤其是视觉部分,不是线程安全的。 放弃这个想法,而是优化导致表单需要很长时间创建的代码。 你还没有告诉我们缓慢的部分是什么。 如果您能回答这个问题,也许我们可以建议一种加快速度的方法。
一般来说,除非您对一段代码进行了分析并确切地知道问题所在,否则不可能很好地提高它的性能。 否则,你只是在浪费时间。
Creating forms in a thread simply will not work. The VCL , and especially the visual portion, is not thread safe. Give up on that idea, and instead optimize the code which is causing the form to take a long time to create. You haven't told us what the slow part is. If you can answer that, perhaps we can suggest a method of speeding it up.
In general, it is not possible to do a good job of improving the performance of a piece of code until you have profiled it and know exactly what the problem is. Otherwise, you're just wasting your time.
解决方案并不容易,因为
线程需要各自的
线程有一个消息循环
您是否需要同时使用所有表单? 如果没有,您可以将创建推迟到应用程序空闲的时间(即 TApplicationEvents.OnIdle)。 或者只是显示一个漂亮的进度条:)
The solution won't be easy, as
thread requires the respective
thread to have a message loop
Do you need all of the forms at once? If not, you could defer the creation to a time where the application is idle (i.e. TApplicationEvents.OnIdle). Or just display a nice progress bar :)
正如 Riho 指出的那样,表单创建不应该占用时间。 不过,可能需要时间的是您放入该表单的构造函数或 OnCreate 事件中的所有代码。
按照克雷格的建议,分析您的代码,以便您知道哪些代码占用最多时间。 然后看看是否可以将部分代码移至单独的线程中。
As Riho points out, form creation should not take up time. What can take time though, is all the code you put in the constructor or the OnCreate-event of that form.
Profile your code, as Craig suggested, so that you know what code takes up the most time. Then see if you can move some of that code into a separate thread.
如上所述,您必须在 VCL 线程中创建表单。 但是,您不需要在那里做所有事情:
如果您的表单有大量图像数据,您可以从表单中删除它,并将其放入资源文件中(或仅使用原始图像文件)
在表单的构造函数中,开始一个后台线程从资源中读取图像数据并执行任何其他缓慢的操作。 重写表单 OnShow 事件以确保它在显示表单之前等待后台线程完成。
As above, you must create the forms in the VCL thread. BUT, you don't need to do everything there:
If your forms have lots of image data, you could remove that from the forms, and place it in a resource file (or just use raw image files)
In your form's constructor, start a background thread to read the image data from resources and do any other slow things. Override your forms OnShow event to ensure it waits for the background thread to complete before the form is displayed.
只需在窗体 OnCreate 上放置一个 PostMessage,并在窗体上编写一个过程来处理 postmessage。
这样,所有需要时间的代码都可以从 OnCreate 方法中删除。
不过,我确实同意,仅在需要时创建表单,然后确实实现一些逻辑来决定是否在关闭时释放它。取决于加载时间和用户再次需要它的机会。Jens
Fudge , 弓箭软件
Just put a PostMessage on the forms OnCreate, and wirite a procedure on the form to handle the postmessage.
In that way, all the code that takes time, can be shoved out of the OnCreate method.
I do agree though, only create the form when it's needed, and then indeed implement some logic to decide if your going to free it upon close, or not.. Depending on loadtime and chance that the user will want it again..
Jens Fudge, Archersoft
我无法想象表单创建需要花费如此长的时间才能需要线程来解析。
如果数据量很大,请尝试限制最初显示的数据量。
I can't imagine what would take so long in form creation that would need threads to resolve.
If it is huge amount of data then try to limit the amount shown initially.
这是我们之前使用过的快捷方式,用于在创建时需要执行大量流程的表单。 在表单上放置一个 TTimer 并将其设置为 false。 表单的 OnCreate 启用它。 然后将 OnCreate 中的所有代码放入 OnTimer 事件中。 将间隔设置为 250 到 500 就足够了。
这不是一个优雅的解决方案,但很简单。
This is a shortcut the we have used before for forms that have a lot of process to do on create. Drop a TTimer on the form and set it to false. OnCreate of the form enable it. Then put all the code you had in OnCreate into the OnTimer Event. Setting the Interval to 250 to 500 is enough.
This is not an elegant solutions, but its simple.
正如我之前所说,有一些大的形式。 DFM 文件大约有 3mb(当然包括图像数据)。
实际上,我认为大部分创建时间是由于创建时间而不是执行的代码造成的。
但也许我会在应用程序空闲时拆分它们并创建它们,当前的加载时间并不是很大(例如 4 或 5 秒),但我会研究它。 谢谢你的回复。
there are some big forms out there as I said earlier. the DFM file is like 3mb (including the image data of course).
I actually think that most of the creation time is due to that rather than the executed code.
But perhaps ill split em and create them when app is idle, the current loading time isnt really big (like 4 or 5 seconds) but ill look into it. thanks for ur replies.