Ok, first of all, the global Session is a method, not an object. When referring to it from within a Session object (the one you see in your project) you should refer to it as Self. Anywhere else, use Session.
Second, if you will be referring to the session a lot, create a local variable (as you have done above with
dim s as Session) to prevent calling the method more than once. The reason for this is that the global method can be an expensive call cpu-wise.
Third, if you’re thinking about creating a property on a class in or Module of type Session or WebSession, don’t… and especially don’t name it Session. Bad things happen when you hold hard references to Sessions, ranging from leaking Sessions themselves (preventing them from being destroyed) to leaking data between sessions.
Now it’s worth keeping in mind whenever code is running, what the context is at that very moment.
If the code is running as a result of an event on any instances of the built-in classes whose names start with “Web” you can pretty much be sure that the code is running in the context of a session. That is, calling the Session method will refer to the session of the browser which triggered the event.
Any other code, particularly events on objects like Timer, any of the TCPSocket subclasses, Shell objects, Thread and the App class itself have no idea about context. In other words, when events fire, it has no idea what, if any, session is also currently running code. This is part of the reason for WebThread and WebTimer exist, because they have been modified so they can figure out what the session is that they belong to.
Once you know the context, you can figure out whether you need to do anything special to access a session. If you’re in a session context, there’s nothing to do. If you’re not, you will need to give the framework a hint by creating a WebSessionContext. New in Web 2.0, it is possible to create a session context using just the identifier of a session. Let’s say you’re creating a class that needs to know which session it is connected to. In the class, you’d add a private property, maybe call it mSessionID. In the Constructor, you could write
mSessionID = Session.Identifier. Then whenever you need to access the session, you should first create a local property (in code) so it will automatically be destroyed when it goes out of scope:
var ctx as New WebSessionContext(mSessionID)
- If you’re already in the session that matches the identifier, it’ll do nothing
- if a session with the supplied ID doesn’t exist, an exception will be raised.
- If the supplied ID doesn’t match the current session, an exception will be raised.
- otherwise, a context is created and you can continue.
Now there’s a lot of confusion about what WebSessionContexts are, so I should probably clear that up now. WebSessionContexts are a hint to the web framework to help it resolve which Session instance (and thereby browser) it should be communicating with at any given time. Creating a WebSessionContext instance adds it to the top of a global stack of contexts and destroying one (or letting it go out of scope) removes it from the stack. It’s very important to understand that when code is running that did not originally come from within a session, it will always be sent to the context that was last added to the stack.
If you are using multiple contexts, always check that session.Identifier matches the identifier you expect, or even better, just don’t mix contexts.