AppStart behaviour

Zenerdiode

Active Member
Licensed User
I'm unsure if a bug or not; but if AppClose is called in a Sub called from AppStart and I have a Form1_Close event Sub, when Sub Form1_Close has completed, execution is returned to and continues in AppStart. This only happens in Optimised Compiled applications. In the IDE or legacy copiled apps, it doesn't. This is how I thought it should behave.

Anyway, that was such a feeble explanation, I've attached some source that demonstrates what I'm trying to say. :)
 

Attachments

  • CloseTest.sbp
    888 bytes · Views: 258

agraham

Expert
Licensed User
Longtime User
When optimised compiled this is the startup sequence of calls in Basic4ppc sysntax
B4X:
 Globals
 Main.App_start
 If  ShownForm <> null Then
    Application.Run(ShownForm) [COLOR="SeaGreen"]' this returns if AppClose is called within[/COLOR]
 End If [COLOR="seagreen"]' the app terminates here[/COLOR]
Form1.Show doesn't actually Show Form1, it creates it and assigns it to ShownForm. The call to the .NET Application object Run method, passing it ShownForm as the main form of the application, actually creates the Windows Message queue for the application and draws the Form. AppClose actually translates to Form1.Close but until the message queue is created the Form cannot receive the Close message so the AppClose call is ignored.

There's a bit more going on than that but the general idea is correct. This sequence is why App_Start terminates the application if it completes without a Form being shown. There is no further code to execute so the application thread exits. If a Form is shown the application thread runs the message loop and stays alive till the application is closed and the message loop terminates.

In the IDE the startup is different as it is an interpreted environment. The interpreter sees the AppClose statement and does precisely that!

EDIT: The corollary to the above is to not perform a Form.Show until you know the application is to start. Then the behaviour should be the same in the IDE and when compiled.
 
Last edited:

Zenerdiode

Active Member
Licensed User
I didn't mention that this was for Desktop compilation. Its sometimes a dilema as to where to place the Form1.Show. If there is a lot of initialisation code in AppStart; showing the form early leaves it unresponsive until complete. Showing it late has your impatient users 'gunning' the application and you then have three instances of it open at the same time...

Here I have to show the form first, because I use Door to set MinimizeBox=True and MaximizeBox=False - they have to be applied to the form once its constructed. I also have a command line argument tha can set the form's WindowState to Minimized; if it is minimised, applying the MinimizeBox and MaximizeBox as above doesn't work.

The above is academic really as:
The corollary to the above is to not perform a Form.Show until you know the application is to start. Then the behaviour should be the same in the IDE and when compiled.

If you move Form1.Show to the end of AppStart in my little example you get an error:

Error loading program.
Cannot access a disposed object.
Object name: 'CEnhancedForm'.


It stands to reason, because I've already killed it with the AppClose above. So the upshot is that in an Optimised Compiled application, all the code in AppStart has to run. This would normally go un-noticed, however it was brought to my attention as I have a logging file created in AppStart - that is not required if the application does not have to run.
 

agraham

Expert
Licensed User
Longtime User
So the upshot is that in an Optimised Compiled application, all the code in AppStart has to run
Yes, that is the implication of the startup code fragment that I posted above. You could set a global flag if any initialisation code invokes AppClose and test it in subsequent initialisation code to see whether to actually perform the initialisation or not bother.
 
Top