Pooled Objects and Initialization Control in VS.NET : Page 3
One of .Net's more obvious benefits for today's Visual Basic developers, is the ability to easily create poolable objects using Visual Basic.NET. The author demonstrates how a web application that uses poolable objects, can show a 50% performance boost in the rate of transactions per second when pooling is enabled. The article also covers things such as application configuration, string resources, page templates, and using XSL stylesheets.
by Joseph Geretz
Dec 15, 2001
Page 3 of 3
'Arm and Fire' Methodology
These are simply a few examples of where the technique of using class private variables to cache data between transactions for pooled objects, can be useful. No doubt this technique can be useful in other situations. I’m sure as well, that other solutions could be proposed for these situations. Again, this technique is simply an additional method which is available to developers. It should be either used or avoided, as appropriate.
The second point is that I’ve used an 'arm and fire' methodology in order to have my objects update themselves. The Refresh method is the arming event, however the firing of the actual data refresh does not occur until the class is called upon to perform the next transaction. This is significant since it prevents all pooled objects from
an unnecessary simultaneous refresh, which could destroy performance for a transaction which was actually in progress while all this mass data refresh was occurring. Indeed, on a system where the arming event occurs frequently, a given pooled instance might actually avoid participating in one or more refresh operations since it will not refresh until it is actually called upon to execute a transaction.
It is true that many different mechanisms could be used to trigger the arming event. One such mechanism which comes to mind is the use of the FileSystemWatcher object. In my scenario, were I to adopt this method, I would still use a separate trigger file. Since there are multiple base data files, I would not want the trigger to be based on a data file since that could have the effect of triggering the arming event before all modified data file were in place. The advantage to the use of the FileSystemWatcher is that the arming event could be initiated by any client, even one not running in the same AppDomain as the pooled classes are. The disadvantage to the FileSystemWatcher is that, from my perspective, this builds up the complexity of the object which is something I generally avoid where I can. Admittedly, in the absence of benchmarks this last observation is somewhat subjective, but hey, it’s my code. Feel free to use the FileSystemWatcher, or any other mechanism you’re comfortable with in your own software. In the final analysis, the specific mechanism for the arming event does not change the fundamental behavior or detract from the significance of the arm and fire methodology, which is available to us, for use in the appropriate scenarios.
A few final points:
I use a GUID for initialization markers since a GUID is practically guaranteed to be unique. This means we don’t need to explicitly choose a new initialization marker and we don’t need to worry about reusing a marker which is still in use by a loaded class. (Although technically speaking, this occurrence is
possible, it is improbable to the point where we can safely deem it
impossible. I’d be more worried that perhaps both of my replicated database servers, or that two disks in my RAID pack, might fail simultaneously. The use of a GUID is at least as robust,
and probably far more robust, than either of these fail-safe’
mechanisms. Extremely cautious developers may find comfort in the draft
specification for UUID's and GUID's at http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt.
In the Refresh method I set the shared GUID to , rather than immediately issuing a new GUID. I can argue both sides of the issue, but I chose this approach since it leverages the algorithm which is already in place to deal with the first object instantiation. The Refresh method doesn’t need to be shared, but sharing it provides syntactic convenience since it can be called without having to explicitly create an instance of the class (as you can see in the script snippet below).
In order to access the shared members for the loaded classes, the code which calls refresh must be running in the same AppDomain (i.e. process). For an IIS application, that means that the code must be running in an ASPX script loaded from the application web site. I’m using the following script on the web site I’m currently working on. Naturally I’ll be dressing this up, fronting it with a management HTML page, but I just got this working recently and this script does the job for me for now.
(Remember, depending on the isolation level of your application, running this script might affect classes in other applications as well, if they are running in the same process.)
The methodology presented here is not specific to Visual Basic.NET, or even to .NET in general. This technique can be used for any environment which supports object pooling and for any language which supports shared variables among multiple class instances. With .NET’s new object oriented features and pooling capabilities, new vistas are opened, and new possibilities are available to Visual Basic developers. I hope that this tip will contribute in some small way to help you make the most of this new and exciting environment.
If you'd like to download this article in Acrobat PDF
stop by my Web site at http://www.FPSNow.com
and follow the links to my Articles page or to my FTP server to download Pooled
Joseph Geretz is the founder of Focal
Point Solutions, Inc., a consulting firm serving clients in the
New York metropolitan area. He has been working with Microsoft
technologies, developing with VB and COM, since 1994 (back then
they called it OLE). His primary focus these days is on N-Tier systems,
using Microsoft DNA tools and methodologies. His development
environments of choice these days are Visual Basic 6 and Visual
Studio .Net, although he has fond
memories of COBOL, from an earlier, more stateless era.