I’m confused about why I can’t user a Thread or a Timer object in a web app, without causing a SessionNotAvailableException. Where can I find a description of how to use such things in my app, which is fairly useless without being able to have server-side threads and/or timers. I’ve read a bunch of confusing stuff about WebSessionContexts, but the help docs don’t shed any (visible) light on the issue.
WebTimers are no use to me - I can’t trigger them more than once, and I believe they are client-side things.
The problem is that Threads and regular Timers fire on the main thread, with no session information associated with them and the underlying web framework relies on knowing what the current session is to figure out what your code means when you say WebPage1.Show.
The solution to this is for you to create an instance of WebSessionContext in the Action event which points to the session that you want it to affect. WebSessionContexts are hints to the web framework as to which session they should be interacting with.
Your best bet will probably be to create a timer subclass which has a WeakRef to the session to which it belongs and then do something like this in the Action event:
If mySession<>nil and mySession.value<>nil then
Dim wsc as new WebSessionContext(WebSession(mySession))
// Run your code here
The session no longer exists... don't do anything.
I created a custom Timer class, embedding the above ideas, and it seems to work fine. Thanks.
Make sure you test your solution with multiple browsers and multiple simultaneous sessions just to be sure it’s all working the way you expect when there is more than one user hitting the app at the same time.
I still think this is a kill or cure remedy, can we expect a real solution sometime in the near future?
This bug is so long known that i am not very positive that it will ever be seriously solved.
IMO loosing the sessioncontext in a timer or thread is a bug. This should never happen and could be a security risk.
Andre, what context should be given to code on the main thread?
The calling session context as a parameter/returnaddress should be saved in the calling sequence. There should never be a question which session started the timer or thread.
Sorry i misspelled your name, Thom.
What do you mean the calling session? The one that created the object? The one that triggered Run in the case of a Thread? What about Timer, should it be the session that last changed the period?
Also, since Timer and Thread are part of the core framework, these changes would apply to the desktop as well. And, since Thread and Timer are built in C, there’s a lot of work to connect the sessions in even if the logic could be worked out.
I can’t speak for Xojo any more of course, but I wouldn’t expect this to be something that would be changed. There are too many logic problems.
I think that this problem is much less in a desktop application, if there the ‘same’ thread or timer is started i would reconsider the design. However in a web application it’s more or less standard procedure that the ‘same’ thread and timer are started from various sessions.
You dodged all my questions.
In general, in a web app, in which case you using threads (server side)?
From the main thread, I see interest: new thread to save the database for example.
But a thread from a session? Perhaps to write files to disk.
I use threads for resizing pictures that are scaled to a size that fits the sessions browser window and the display of database records in listboxes which size must fit that part of that window. Resizing the pictures and the access to the database(s) is a per session activity.
These are all serverside threads.
I haven’t used a webthread because for the mentioned activities they probably won’t work, besides that there was a time that there were problems with webthreads and their use was blocked and i haven’t seen a mention that it’s safe again to use them, probably i have missed that part.
ok, thank you Andre, but if:
- The client requests a web page
- The server receives the request and the size of the browser, load the images, resize images based on the browser size, and sends it (page with images) to the client, I do not see the interest of threads.
There is already a thread of session, and the interest is that the client receives the page as quickly as possible, run multiple threads (on one core) finally take longer. Unless you use a separate web server to send images? or you resized the images of the entire app (not just the current page) in the background?
Unless you think that the Xojo app sends the web page (HTML and text) to the client browser, and then shortly after, the images when the thread is finished work? hmm, maybe.
Every session can use hundreds of pictures but they don’t have to be all at once be available on the browser but the browser must be able to switch fast from one to the other with (almost) no lag. The program can show a whole row or several rows of thumbnails of pictures all originally of different size and format and at the same time show the contents of tables in the database.
The advantage of using threads is not that each individual action is faster but that the action goes on while the user is looking to some pictures and data in the listboxes.
ok, thank you Andre. You use Xojo methods (webFile/webImageView) to send your images to the browser? I remember that there were many problems with this method (blocking the application, delays …), it works well now?