views:

2480

answers:

8

Hello everyone.

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.

+22  A: 

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.

Craig Stuntz
Actually, creating a window in a thread different from the main UI thread is a completely legitimate idea in Win32 that has its uses. This has nothing to do with "VCL being thread safe". If I want to have 3 threads each with its own message loop, why would VCL care? The message loops should not be talking to each other, they are in separate contexts (i.e. no problem with thread safety).
Milan Gardian
Milan, Win32 window <> VCL form. He wants a VCL form, and you simply can't do that, no matter how tad you want to.
Craig Stuntz
+4  A: 

The solution won't be easy, as

  1. the Delphi VCL is not thread safe
  2. creating windows in another 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 :)

Heinrich Ulbricht
I up-voted this answer for pointing out that you do not need to create all the forms at once, but a progress bar would drive me up the wall, as a user. :)
Craig Stuntz
Yep, basically I feel the same. But if it is inevitable to do lengthy operations at startup then it is better to have one than not. I once forgot to show one and customers terminated the app because they thought it hangs :-/ But anyway - you are certainly right suggesting further optimization.
Heinrich Ulbricht
A: 

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.

Riho
+2  A: 

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.

Vegar
A: 

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.

Thad
A: 

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.

A: 

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.

Roddy
A: 

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