Don’t Use Implicit Page Names

On page 50 of the UserGuide-Development.pdf it says:

[quote]Don’t Use Implicit Page Names
Store a reference to a page in a variable or property rather than using the name of the page as an implicit reference. Implicit references have to be looked up by the framework which takes longer than simply accessing a reference that is stored somewhere. For example, rather than doing this:
WebPage1.Show

Do this:
Dim page As WebPage1
page.Show
[/quote]

Why is the first one slower? And what is the danger of doing this in a multi-user Web app (my Web apps seem to run fine with WebPage1.Show)?

When you have WebPage1 as an implicit instance, we create a module called WebPage1, which contains a class WebPage1, and a method WebPage1. When you call WebPage1.Show, you’re calling the global method. This attempts to detect the current session and determine if you already have an implicit instance of WebPage1. It will create one if you do not. This takes time.

Conversely, if you have implicit instance off, none of this applies. WebPage1 is just a class.

So if I have an app with ten web pages each as an implicit instance it will take longer to launch as they are all being built behind the scene. If they were not implicit instances then they would only be built as I created them. Have I understood correctly?

So it is not a matter of danger, more of efficiency.

Not exactly. Implicit instances are still not created until you need them. Imagine the code

WebPage1.TextField1.Text = "Hello World" WebPage1.TextField1.Enabled = False WebPage1.Show

You’ve just called the “find WebPage1” routine 3 times. It’s a waste of time. Instead, while still using implicit instance, you could do

Dim Win As WebPage1 = WebPage1 Win.TextField1.Text = "Hello World" Win.TextField1.Enabled = False Win.Show

Which will do precisely the same thing, but need to perform only one lookup instead. If you have implicit instance turned off, you would Dim Win As New WebPage1 first, requiring no lookups at all. You would need to maintain your own reference to the window however.

Implicit instance can lead to hard to find bugs however, especially when you’re trying to create or dispose of windows. Stack overflows caused by recursion, and memory leaks due to a window not actually being destroyed are the most common issues.

I write external modular code that can be called by both Desktop and WE apps, so I want the Window name to be exactly the same (i.e. NOT Window1.Show for desktop and Session.WebPage1.Show for WE, but Window1.Show for both. This works, but is a real pain). Currently I have all my WE windows as Implicit in a multi-user program and it works, but suggestions are this is potentially unstable.

I have another solution working, but am not sure if I am heading for danger again:
• define all WE pages as default implicit windows i.e. WebPage1
• create a module and define a doppleganger for each WebPage (spelled slightly differently) e.g. WinPage1 As WebPage1
• in the app’s Open event include the line WinPage1 = New WebPage1
• now both the Desktop and WE versions of the app can reference the same window name WinPage1.Show from anywhere.

Will this remove the problems of: having to be looked up by the framework, stack overflows caused by recursion, and memory leaks due to a window not actually being destroyed?

In my experience, the biggest problem with using implicit instances for WebPages is that you can end up with wrong “Session”, especially in push scenarios. The implicit instance is one of those pieces of syntactic sugar that makes WE approachable and easy to get productive with quickly.

With my biggest WE projects, I’m currently using implicit instances, but not using “Session”. Instead, I’m using a ubiquitous “mySession” computed property that uses app.SessionForControlId (<-- from memory, might not be exactly correct) to get the Session for the control/page in question.

-Brad

@Richard “Brad” Hutchings When I started WE apps I prefixed all my web pages as Web… then created a Session Web Page equivalent which was good in that when the user Session dies all user memory is cleared, but this was a nightmare for keeping cross-envrionment code.
Then I test implicit WebPages with multiple users logging in at once to see if there was any data-leakage between user windows and found none. Now I find that is a dangerous technique despite all WE example doing this.

Eventually I hope that dozens of users will be logged into my WE apps and the cgi run for weeks without memory problems, and I need to know the best technique to achieve this.

The various memory leaks were mostly independent of the global Session object and implicit page references. The main issue with these two things is that they make WE very approachable but have a tendency to get the developer in trouble when apps get complicated. The other problem with “Session” is that it behaved (behaves) as if it was implemented by stack sniffing rather than an easily understood lookup. And since the implicit WebPage needs the current Session to work, this could cause some issues with getting the right instance of a page in push scenarios.

Where I am right now with this stuff is that I think there might be a middle ground between what’s approachable (but gets confusing) and what’s less mysterious (but more bookkeeping). I know, not terribly helpful direct advice, but I’m still sorting it out.