WebPage: Instantiate or not? Best practice?

Well… let’s talk about this.

The web framework (both 1.0 and 2.0) are designed to keep user data separate. That is, that only one user’s data is being accessed at any given time by default, and while WebPage instances are unique per session, there are patterns in a web app that can cause cross contamination:

Static Variables

Static variable are, by definition, persistent across all instances of a class and using them can cause data to cross over into other sessions. For example, if you were to:
  1. Create a new web project
  2. Drag a label onto WebPage1
  3. In WebPage1.Open(ing) put the following code:
Static n as integer
n = n + 1
Label1.value = n.ToString
  1. Run and connect to the app a few times.

Each time a new user comes to your app, n is incremented. If you did this to save a user’s password in a Static, it would be available across all sessions.

In other words… do not make a WebPage instance Static.

Global Properties

Another way you can get yourself into trouble is by using properties on Modules or Shared Properties on Classes. Just like in a single-user project, these things are global across all sessions, so it's important to keep track of what you are doing. The easiest way to keep properties separate is to add them directly to the Session object.

If you wanted to organize session-specific properties together, I suggest doing so using a class that is added to a Session as a property itself. For instance, you could make a class called Settings which has Name, Company and Phone properties and add an instance (lets say userSettings) of that class to the Session on Open(ing). When you need that information, you would refer to it like this:
Var name As String = Session.userSettings.name

So in terms of WebPages, if you’re going to keep track of them yourself, make sure you put them on the Session itself. Keep in mind that the Session does already keep track of them for you, so you don’t have to unless you will need to refer to it again later. This brings me to something I would be remiss not to discuss at this point…

Memory Leaks

You can't have a discussion about instantiating WebPages at runtime without touching on this. Memory Leaks are, by definition, memory that gets "leaked" because objects cannot be destroyed when the program is done with them.

The easiest way to create a memory leak in a web project is to add a property to a WebPage or WebControl (or one of its subclasses) which refers to an object which can contain that object. For instance, if you were to add a WebContainer to your project and for simplicity’s sake, you add a property which refers to the WebSession to which the container belongs. The problem comes in when the user has gone away and the app is trying to clean things up. Even though the Session instance gets released from the app itself, because there is a reference to the Session from the container, it cannot be destroyed. Here’s an example of what I’m talking about:

Inherently, WebSessions keep references to the WebPages contained within. The same goes for controls on a WebPage. If you were to do what I described above, and create a reference from a WebContainer back to the Session itself (the blue line), you’ve created what’s called a circular reference. When the Session is no longer needed, the web framework releases its reference to the Session instance. Normally this would cause the underlying framework to destroy the session and then the pages and then the container as each of the references to those things went away. If however you had created the extra reference from the container to the session, it will never be destroyed because there’s always a reference.

In real world terms, imagine a game where people hold hands (okay, not now in the midst of the 2020 pandemic, but bear with me for a moment). In this game, you can only release one hand if the other hand is not holding onto something else.

  1. Three people are playing. Mike, Carol and Alex.
  2. Carol holds onto one of Mike’s free hands.
  3. Alex holds onto Carol’s free hand.

Now at any given time, this chain can be broken up if Alex or Mike lets go of Carol’s hand. But what happens if Alex takes Mike’s free hand. According to the rules, no one can let go of anyone else until the end of the game.

5 Likes