StrataFrame Forum

Form loading Delay

http://forum.strataframe.net/Topic2755.aspx

By Brad Vick - 9/12/2006





Our application consists of a parent MDI form with a menu, each item in the menu corresponds to a child form. Each child form is a separate assembly, so when the menu item is clicked a child form is instantiated. Also each child form references/uses a business object (separate assembly) to populate grids and such. When first loading the application, the first child form that is opened takes alot longer to load than any subsequent child forms opened. I have tried using ngen.exe to create a native image and avoid the JIT compiling each time, this did not help. I suspect that it has to do with some initializations of the business object, like opening the database connection for the first time. Is there anyway to move these initializations like opening the database connection into the initialization of the parent application? Are there any other suggestions on how to eliminate the delay in the first child form opened?



Thanks,

Brad
By Brad Vick - 9/12/2006



Another note I forgot to mention. Each of the child forms inherit from a base form.
By Trent L. Taylor - 9/12/2006

The reason the delay occurs has nothing to do with the BO (unless you are pulling back a large number of records from the server).  If the BO is just instantiating, then this is not your issue.  The connections to the data is not connected unless you request data, and this is extremely fast and definiltey not recognizable.

The reason this seems to take a little longer has do with the structure of your assemblies.  There is nothing wrong with this approach, but the reason you are seeing a delay more than likely has to do with the fact that the assembly containing the child is being loaded into memory.  .NET only loads assemblies as they are needed.  Even if you have 100 references to unique assemblies, the referenced assemblied are not loaded into the AppDomain until some class is called or referenced that depended upon that assembly.

If you really want to see where your time delays are happening then you may want to invest in a product such as a .NET Profiler (Red Gate has one) which breaks down each line of code and creates reports telling you exactly where your time delays are occurring. 

This is something that we do all of the time, and is common place for most any application.  But I am confident your problem here is not in the BO arena but more than likely something else that is taking place when the assembly is loaded.

By Trent L. Taylor - 9/12/2006

FYI...if you want some more precise explanations you are welcome to post your project (or at least an example of the issue) and we can take a closer look at it and help you discover where your time is being consumed. 
By Brad Vick - 9/12/2006



Is it bad practice to load up all the required assemblies up front? Or atleast the most used ones, like Microfour, and Devexpress stuff?
By Trent L. Taylor - 9/12/2006

Not neccissarily...it just depends on what you are trying to accomplish.  Sometimes this is a very good approach because you can use reflection and get all of the references in your application and manually load the assemblies into the AppDomain while showing a "Loading" screen and thermo to the end-user.  This takes the "wait time" out of the forumla, especially since the end-user is not just sitting there waiting for the form to come up.

We have done this a time or two in scenarios when there will be a large number of assemblies that are going to loaded right off the bat.  We will create a splash window and show it in the AppMain.vb or program.cs file in the InitApplication method.  The splash window has a label and a progress bar showing the whatever text you want and then the progress bar has the max count set to the number of assemblies that are going to be loaded.  When then cycle through the references and manually load them into the AppDomain.  Generally we close down the splash screen in the Shown event of the first form that appears.  So obviously you will want to have a shared class or property that exposes the instance of the splash screen.

Let me know if this doesn't make any sense. Smile

By Brad Vick - 9/12/2006





That does make sense. I will talk it over with the rest of the crew and decide if that is the approach we want to take. Thanks alot for the advice.
By Trent L. Taylor - 9/12/2006

Sure. Glad to help.
By Brad Vick - 9/12/2006





We want to load up all the MicroFour and DevExpress assemblies up front. Do you have a snippet of code that shows how to load an assembly to the AppDomain?
By Trent L. Taylor - 9/12/2006

It will look something like this:

Dim loName As System.Reflection.AssemblyName

For Each loName In System.Reflection.Assembly.GetExecutingAssembly().GetReferencedAssemblies()
        AppDomain.CurrentDomain.Load(loName)
Next

I did not test this code, but this should get you going in the right direction.

By Brad Vick - 9/12/2006





I implemented code that recursivley loads all the referenced assemlibes into the appDomain. Unfortunately it did not help with the first child form loading, still takes twice as long for the first one to load than the rest. Any other ideas? I will continue searching google.
By Trent L. Taylor - 9/12/2006

You may need to take into account the references in the child assembly.  Are they loaded as well?  You can manually load them into the AppDomain.  Bottom line is that you need to know why this is taking longer to load and you need to see where your stop gap is.  One thing you can do is use some of the System.Diagnostics classes to get an idea of where your time is going.

You can use the StopWatch command.  Start it and Stop it in certain locations and popup a message box after certain events showing the time.  This will help you to start learning where your time loss is.

Just FYI, this is always an issue if you have too many assemblies that need to be loaded at the same time on the same form....but you can overcome this by pre-loading the assemblies.  I promise that this works, but you are going to have to expand the code I gave you earlier by making sure any assemblies in the child are loaded as well.  That is why it is fast the second time you go in....the assemblies are loaded in the AppDomain.

One thing you can do is cycle through the loaded assemblies in the AppDomain.CurrentDomain before and after the child is loaded.  You will see that there are more assemblies loaded after than before.  This might help you pinpoint which assemblies you are missing.