<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Fabulous Adventures In Coding : ASP</title><link>http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx</link><description>Tags: ASP</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>It Already Is A Scripting Language</title><link>http://blogs.msdn.com/ericlippert/archive/2009/06/24/it-already-is-a-scripting-language.aspx</link><pubDate>Wed, 24 Jun 2009 18:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9801664</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>50</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9801664.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9801664</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;My recent post about the &lt;EM&gt;possibility&lt;/EM&gt; of &lt;EM&gt;considering maybe someday perhaps&lt;/EM&gt; adding "top level" methods to C# in order to better enable "scripty" scenarios generated a surprising amount of immediate emphatic pushback. Check out the comments to see what I mean.&lt;/P&gt;
&lt;P&gt;Two things immediately come to mind.&lt;/P&gt;
&lt;P&gt;First off, the suggestion made by a significant number of the commenters is "instead of allowing top-level methods, strengthen the using directive." That is, if you said "using System.Math;" then all the static members of that class could be used without qualification.&lt;/P&gt;
&lt;P&gt;Though that is a perfectly reasonable idea that is requested frequently, it does not actually address the problem that top-level methods solve. A better "using" makes things easier for the developer writing the &lt;EM&gt;call&lt;/EM&gt;. The point of top-level methods for scripty scenarios is to make it easier on the developer writing the &lt;EM&gt;declaration&lt;/EM&gt;. The point is to eliminate the "ritual" of declaring an unnecessary class solely to act as a container for code.&lt;/P&gt;
&lt;P&gt;Second, and more generally, I am surprised by this pushback because of course &lt;STRONG&gt;C# already is a scripting language, and has had this feature for almost a decade.&lt;/STRONG&gt; Does this code fragment look familiar?&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&amp;lt;%@ Page Language="C#" %&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;lt;script runat="server"&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp; void Page_Load(object sender, EventArgs e)&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// whatever&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;lt;/script&amp;gt;&lt;BR&gt;...&lt;BR&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Where's the class? Where are the using directives that allow "EventArgs" to be used without qualification? Where's the code that adds this method group to the event's delegate? All the ritual seems to have been eliminated somehow. That sure looks like a "top-level method" to me. &lt;/P&gt;
&lt;P&gt;Of course we know that behind the scenes it isn't any such thing.&amp;nbsp;ASP.NET does textual transformations on the page to generate a class file. And of course, we recommend that you use the "code behind" technique to make a file that actually contains the methods in the context of an explicit&amp;nbsp;(partial) page class, to emphasize that yes, this is a class-based approach to server-side processing.&lt;/P&gt;
&lt;P&gt;But you certainly do not have to&amp;nbsp;use "code behind". If you're an ASP traditionalist (like me!)&amp;nbsp;and would&amp;nbsp;rather see C# as a "scripting language" that "scripts" the creation of content on a web server, you go right ahead. You can put your "top level" methods in "script" blocks and your "top level" statements in "&amp;lt;% %&amp;gt;" blocks and you'll thereby&amp;nbsp;avoid the ritual of having to be explicit about the containers for those code elements. The ASP.NET code automatically reorganizes your "script" code into something that the C# compiler can deal with, adding all the boring boilerplate code that has to be there to keep the compiler happy.&lt;/P&gt;
&lt;P&gt;But consider now&amp;nbsp;the burden placed upon the developers of ASP.NET by the language design. Those guys cannot simply parse out the C# text and hand it to the C# compiler. They've got to have a solid understanding of what the legal code container topologies are, and jump through hoops -- not particularly difficult hoops,&amp;nbsp;but hoops nevertheless -- to generate a class that can actually be compiled and executed.&lt;/P&gt;
&lt;P&gt;This same burden is placed upon &lt;EM&gt;every&lt;/EM&gt; developer who would like to expose the ability to add execution of end-user-supplied code to their application, whether that's in the form of adding extensibility via scripting, or by enabling evaluation of user-supplied expressions (such as queries). It's a burden placed on developers of productivity tools, like Jon Skeet's "snippet compiler", or LINQPad. It's a burden on developers who wish to experiment with REPL-like approaches to rapid development of prototypes, test cases, and so on.&lt;/P&gt;
&lt;P&gt;I am not particularly excited about&amp;nbsp;the convenience of the ability to save five characters by eliding the "Math." when trying to calculate a cosine. The&amp;nbsp;exciting value props&amp;nbsp;are that we might be able to&lt;STRONG&gt; lower the cost of building tools that extend the power of the C# language into third-party applications, &lt;/STRONG&gt;and at the same time&amp;nbsp;enable &lt;STRONG&gt;new ways to rapidly experiment and develop high-quality code.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Of course we do not want to wreck the existing value props of the language in doing so; as I said last time, we also believe that there is huge&amp;nbsp;value in the language design naturally leading professional, large-scale application developers towards&amp;nbsp;building well-factored component-based programs. &lt;/P&gt;
&lt;P&gt;Like all design decisions, when we're faced with a number of competing,&amp;nbsp;compelling, valuable and&amp;nbsp;noncompossible ideas, we've got to find a workable compromise. We don't do that except by &lt;STRONG&gt;considering all&amp;nbsp;the possibilites&lt;/STRONG&gt;, which is what we're doing in this case.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9801664" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category></item><item><title>How To Obtain The Name Of The Client From The ASP Server</title><link>http://blogs.msdn.com/ericlippert/archive/2005/05/09/how-to-obtain-the-name-of-the-client-from-the-asp-server.aspx</link><pubDate>Mon, 09 May 2005 22:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:415763</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/415763.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=415763</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Here's a question about client side vs. server side scripting that I got recently:&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;I want to get the machine name of the client the request is being made from. With ASP I can get the IP address using this code: &lt;SPAN class=code&gt;ipaddr = Request.ServerVariables("REMOTE_ADDR") &lt;/SPAN&gt;But I don’t know how to get the name of the machine. Is there something I could do from the client side?&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;No, the web browser client cannot determine the name of the machine for two reasons.&lt;/P&gt;
&lt;P&gt;First, &lt;STRONG&gt;if it could then the client could be instructed to send the name of the machine to an evil server&lt;/STRONG&gt;. Evil hackers would love to have an &lt;I&gt;internet&lt;/I&gt; web page that harvested &lt;I&gt;intranet&lt;/I&gt; machine names that they could then attack. Knowing the name of a machine is particularly useful for social engineering attacks -- if someone phoned me up claiming to be from our IT department, I'd be a lot more inclined to believe them if they knew the names of all my machines.&lt;/P&gt;
&lt;P&gt;Second,&amp;nbsp;look at it from the other way.&amp;nbsp; Suppose the client magically figures out its name and sends it to the server.&amp;nbsp; &lt;I&gt;Why should the server trust the client?&lt;/I&gt; &amp;nbsp;What stops an evil client from sending a bogus name to the server? Even if the client could send the name, the server can't make any decisions based on that name, so it's kind of useless.&lt;/P&gt;
&lt;P&gt;Clients and servers should not trust each other.&amp;nbsp; In the absence of authentication evidence, clients must assume that all servers&amp;nbsp;are run by evil hackers and servers must assume that all clients are run by evil hackers.&amp;nbsp; Once you accept that fundamental design principle then it becomes much easier to reason about client-server interactions.&amp;nbsp;Think like an evil person!&lt;/P&gt;
&lt;P&gt;Another developer who saw this question suggested running this code on the server:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;name = Request.ServerVariables("REMOTE_HOST")&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;That's a good start but not the whole story. By default this doesn't actually give you the remote host -- it just gives you the IP address again. If you want this to actually give you the name of the remote machine then&amp;nbsp;there's some additional work you have to do. Since we have the IP address then we can do a reverse DNS lookup to see if there is a friendly name associated with that address. Now the server is trusting not&amp;nbsp;an&amp;nbsp;arbitrarty&amp;nbsp;client but rather&amp;nbsp;a specific reverse DNS server.&lt;/P&gt;
&lt;P&gt;Read this Knowledge Base article on how to configure your server to automatically do Reverse DNS lookups when the code above is called.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://support.microsoft.com/default.aspx?scid=kb;en-us;Q245574" mce_href="http://support.microsoft.com/default.aspx?scid=kb;en-us;Q245574"&gt;http://support.microsoft.com/default.aspx?scid=kb;en-us;Q245574&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Note that this will make your server performance worse, and of course is not guaranteed to work if the client machine is disguising its identity via a firewall, etc.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=415763" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category></item><item><title>What's the Difference between WScript.CreateObject, Server.CreateObject and CreateObject?</title><link>http://blogs.msdn.com/ericlippert/archive/2004/06/01/145686.aspx</link><pubDate>Tue, 01 Jun 2004 18:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:145686</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>20</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/145686.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=145686</wfw:commentRss><description>&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;A reader asked me last week&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;I have always used &lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;&lt;FONT face="Lucida Console" color=#000080&gt;Server.CreateObject &lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;in ASP scripts and &lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;&lt;FONT face="Lucida Console" color=#000080&gt;WScript.CreateObject &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;in WSH scripts, because I was unable to find any *convincing* information on the subject and therefore assumed that they were there to be used, and were in some way beneficial... but perhaps they're not?!&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;What exactly is the reasoning behind having additional &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080&gt;CreateObject&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;methods in ASP and WSH when VBScript already has &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080&gt;CreateObject &lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;and JScript already has &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080&gt;new ActiveXObject &lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;?&amp;nbsp; (&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080&gt;new ActiveXObject &lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;is for all intents and purposes identical to &lt;FONT face="Lucida Console" color=#000080&gt;CreateObject&lt;/FONT&gt;, so I'll just talk about VBScript's &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080&gt;CreateObject &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;for the rest of this article.)&amp;nbsp; There are two reasons:&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;1)&lt;FONT face="Times New Roman"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;VBScript and JScript aren't the only game in town.&amp;nbsp; What if there is a third party language which (inexplicably) lacks the ability to create ActiveX objects?&amp;nbsp; It would be nice to be able to create objects in such a language, thus the hosts expose said ability on their object models.&amp;nbsp; (Similarly, IE, WSH and ASP all have "static" object tags as well.)&amp;nbsp; &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;Of course, this is a pretty silly reason.&amp;nbsp; First off, no such language comes to mind, and second, why stop at object creation?&amp;nbsp; A language might not have a method that concatenates strings, but that doesn't mean that we should add one to WSH just because it comes in handy.&amp;nbsp; We need a better justification.&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;SPAN&gt;2)&lt;FONT face="Times New Roman"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;The ASP and WSH versions of &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080&gt;CreateObject &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;are subtly different than the VBScript/JScript versions because they have &lt;A href="http://blogs.msdn.com/ericlippert/archive/2003/10/08/53175.aspx"&gt;more information about the host than the language engine posesses&lt;/A&gt;.&amp;nbsp; The differences are as follows:&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Lucida Console" color=navy&gt;&lt;SPAN&gt;WScript.CreateObject&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt; with one argument is pretty much identical to &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080&gt;CreateObject &lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;with one argument.&amp;nbsp; But with two arguments, they're completely different.&amp;nbsp; The second argument to &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080&gt;CreateObject &lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;creates an object on a remote server via DCOM.&amp;nbsp; The second argument to &lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;&lt;FONT face="Lucida Console" color=#000080&gt;WScript.CreateObject &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;creates a local object and hooks up its event handlers.&amp;nbsp; &lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Console" color=navy&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;Sub Bar_Frobbed()&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=navy&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;WScript.Echo "Help, I've been frobbed!"&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=navy&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;End Sub&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=navy&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;Set foo = CreateObject("Renuberator", "Accounting")&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=navy&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;Set bar = WScript.CreateObject("Frobnicator", "Bar_")&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;This creates a renuberator on the accounting server, a frobnicator on the local machine, and hooks up the frobnicator's events to functions that begin with the particular prefix.&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;Remember, in the script engine model the control over how event binding works is controlled by the &lt;EM&gt;host&lt;/EM&gt;, not by the &lt;EM&gt;language&lt;/EM&gt;.&amp;nbsp; Both IE and WSH have quite goofy event binding mechanisms for dynamically hooked up events -- IE uses a &lt;A href="http://blogs.msdn.com/ericlippert/archive/2003/12/12/53454.aspx"&gt;single-cast delegate model&lt;/A&gt;, WSH uses this weird thing with the string prefixes.&amp;nbsp; &lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Lucida Console" color=navy&gt;&lt;SPAN&gt;Server.CreateObject&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt; creates the object in a particular &lt;I&gt;&lt;SPAN&gt;context&lt;/SPAN&gt;&lt;/I&gt;, which is important when you are creating &lt;I&gt;&lt;SPAN&gt;transactable&lt;/SPAN&gt;&lt;/I&gt; objects.&amp;nbsp; Windows Script Components, for example, are transactable objects.&amp;nbsp; This means that, among other things, you can access the server object model directly from a WSC created with &lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;&lt;FONT face="Lucida Console" color=#000080&gt;Server.CreateObject &lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;, because the object obtains the server context when it is created.&amp;nbsp; Ordinary &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080&gt;CreateObject &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;has no idea what the current page context is, so it is unable to create transactable objects. There are many interesting facets of transactable objects which I know very little about, such as how statefulness and transactability interact, how the object lifetime works and so on. Find someone who writes a blog on advanced ASP techniques and ask them how it works, because I sure don't know.&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;I'll answer the question "what's the difference between &lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;&lt;FONT face="Lucida Console" color=#000080&gt;WScript.CreateObject &lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;and &lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;&lt;FONT face="Lucida Console" color=#000080&gt;WScript.ConnectObject&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;?" in a later blog entry.&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;I answered the question "What's the difference between &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080&gt;GetObject &lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;and &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080&gt;CreateObject &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;?" in &lt;/FONT&gt;&lt;A title=http://weblogs.asp.net/ericlippert/archive/2004/01/14/58700.aspx HREF="/ericlippert/archive/2004/01/14/58700.aspx"&gt;&lt;FONT size=2&gt;this&lt;/FONT&gt;&lt;/A&gt;&lt;FONT size=2&gt; blog entry.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=145686" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/JScript/default.aspx">JScript</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/VBScript/default.aspx">VBScript</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category></item><item><title>VBScript and JScript Don't Mix, at least in ASP</title><link>http://blogs.msdn.com/ericlippert/archive/2004/02/19/76438.aspx</link><pubDate>Thu, 19 Feb 2004 18:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:76438</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/76438.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=76438</wfw:commentRss><description>&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;A&amp;nbsp;reader wrote me recently to&amp;nbsp;describe a problem&amp;nbsp;that I used to&amp;nbsp;hear fairly often:
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" size=2&gt;&lt;SPAN&gt;&lt;FONT color=#000000&gt;I write ASP code using VBScript and a coworker of mine uses JScript.&amp;nbsp; We were wondering if we could combine our code in ASP.&amp;nbsp; However, it does not seem to be working right.&amp;nbsp; Here is an example of where we are having trouble:&lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#000000&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#000000&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=#000000 size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Console" color=#000000 size=2&gt;&lt;SPAN&gt;&amp;lt;SCRIPT LANGUAGE="JScript" RUNAT="Server"&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000000 size=2&gt;&lt;SPAN&gt;Response.Write("&amp;lt;H1&amp;gt;header&amp;lt;/H1&amp;gt;");&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000000 size=2&gt;&lt;SPAN&gt;&amp;lt;/SCRIPT&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000000 size=2&gt;&lt;SPAN&gt;&amp;lt;SCRIPT LANGUAGE ="VBScript" RUNAT="Server"&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000000 size=2&gt;&lt;SPAN&gt;Response.Write "&amp;lt;H1&amp;gt;body&amp;lt;/H1&amp;gt;"&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000000 size=2&gt;&lt;SPAN&gt;&amp;lt;/SCRIPT&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000000 size=2&gt;&lt;SPAN&gt;&amp;lt;SCRIPT LANGUAGE ="JScript" RUNAT="Server"&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000000 size=2&gt;&lt;SPAN&gt;Response.Write("&amp;lt;H1&amp;gt;footer&amp;lt;/H1&amp;gt;");&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" size=2&gt;&lt;SPAN&gt;&lt;FONT color=#000000&gt;&amp;lt;/SCRIPT&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#000000&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=#000000 size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" size=2&gt;&lt;SPAN&gt;&lt;FONT color=#000000&gt;As you can see this code should write:&lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#000000&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#000000&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=#000000 size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Console" color=#000000 size=2&gt;&lt;SPAN&gt;header&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000000 size=2&gt;&lt;SPAN&gt;body&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" size=2&gt;&lt;SPAN&gt;&lt;FONT color=#000000&gt;footer&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#000000&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=#000000 size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=#000000 size=2&gt;&lt;SPAN&gt;but the ASP engine does not&amp;nbsp;render it like that.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;My advice: don't mix languages on one ASP page because, as my correspondent discovered, it doesn't work the way you think it should.&amp;nbsp; The rendering comes all out of order.&amp;nbsp; Why?
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Before you read on, if you don't understand the ASP compilation model you should &lt;A title=http://blogs.msdn.com/ericlippert/archive/2003/09/18/53046.aspx HREF="/ericlippert/archive/2003/09/18/53046.aspx"&gt;read my earlier post&lt;/A&gt; on the subject.&amp;nbsp; To briefly recap, ASP translates the page into a script, sticks the script into an engine, and then clones the engine a bunch of times if it needs to.&amp;nbsp; Every time the page is served, the engine is pulled out of the engine pool, the script is run, and everything just works.
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;So what happens when you have two languages on the page?&amp;nbsp; You need two engines, but the mechanism is the same.&amp;nbsp; The page is compiled up into two scripts, and &lt;B&gt;&lt;SPAN&gt;ASP runs one engine and then the other.&lt;/SPAN&gt;&lt;/B&gt;
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Now it should become clear why this appears to run out of order.&amp;nbsp; From ASP's perspective, the page above turns into two scripts:&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=black size=2&gt;&lt;SPAN&gt;
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;// Jscript&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;Response.Write("&amp;lt;H1&amp;gt;header&amp;lt;/H1&amp;gt;");&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;Response.Write("&amp;lt;H1&amp;gt;footer&amp;lt;/H1&amp;gt;");
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;' VBScript&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;Response.Write "&amp;lt;H1&amp;gt;body&amp;lt;/H1&amp;gt;"
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=black size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;The ASP engine does not maintain any information about which &lt;STRONG&gt;chunk&lt;/STRONG&gt; should execute before another.&amp;nbsp; It gathers up all the script chunks for each language, compiles them, and then &lt;STRONG&gt;runs each engine in turn&lt;/STRONG&gt;.&amp;nbsp; Not only does it lead to seemingly out-of-order execution as shown here, but it also restricts the language blocks from calling each other's methods (because the methods in the not-yet-executed block may not have been initialized yet.)&amp;nbsp; A detailed discussion of how IE solves this problem deserves another blog entry on its own.
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Mixing languages can also lead to performance problems, because it means that each page is now consuming TWO engines from the engine cache, which means more cache misses, larger working set, etc.
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=black size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;While I'm on the subject, note that it is in general a bad idea to put a whole lot of "inline" code into &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;&amp;lt;SCRIPT&amp;gt; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;blocks like that.&amp;nbsp; Ideally you want the server side &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;&amp;lt;SCRIPT&amp;gt; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;blocks to contain only global function definitions, and the &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;&amp;lt;% %&amp;gt; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;blocks to contain only "inline" code.&amp;nbsp; ASP does not enforce that constraint, but ASP.NET does.&amp;nbsp; (The reasoning behind that is long enough to require another post.)
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=black size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;If you really want to have multiple languages on one ASP page, here is a way you can make this work though if you really need to.&amp;nbsp; You could write a bunch of Windows Script Component objects in different languages, which expose methods.&amp;nbsp; You could then write an ASP page in one language that calls those methods in the right order.&amp;nbsp; WSCs are good in ASP because (a) they efficiently cache engine state, just like ASP, and (b) they can use the ASP object model directly if you write them correctly.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=76438" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category></item><item><title>The Tragedy of Thread Happiness Disease</title><link>http://blogs.msdn.com/ericlippert/archive/2004/02/15/the-tragedy-of-thread-happiness-disease.aspx</link><pubDate>Sun, 15 Feb 2004 19:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:73366</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/73366.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=73366</wfw:commentRss><description>&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;A &lt;A title=http://www.joelonsoftware.com/ href="http://www.joelonsoftware.com/"&gt;JOS&lt;/A&gt; reader interested in developing server software asked recently 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Is it possible to determine the number of concurrent threads a server can support from the server's specification?
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/B&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Now, as I've said &lt;A title=http://blogs.msdn.com/ericlippert/archive/2003/12/01/53411.aspx href="http://blogs.msdn.com/ericlippert/archive/2003/12/01/53411.aspx"&gt;before&lt;/A&gt;, I'm no expert on performance tuning multi-threaded applications, but I have picked up a thing or two hanging around the real experts on the IIS team.&amp;nbsp; In fact, the perf teams get questions in this vein all the time from customers, both internal and external.
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;The interesting thing about the question is that it is symptomatic of &lt;B&gt;&lt;SPAN&gt;Thread Happiness&lt;/SPAN&gt;&lt;/B&gt;, a peculiar disease which usually strikes programmers who are relatively new to large-scale multi-threaded software development.&amp;nbsp; &lt;BR&gt;&lt;BR&gt;How do I know that the questioner is getting Thread Happy?&amp;nbsp; Because if they were writing an application where there were two threads or five threads or ten threads then they wouldn't be asking &lt;I&gt;&lt;SPAN&gt;that&lt;/SPAN&gt;&lt;/I&gt; question.&amp;nbsp; They'd be asking "&lt;B&gt;&lt;SPAN&gt;I want to write a server app with two/five/ten/whatever threads -- how buff does the server have to be?"
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;
&lt;P&gt;But they're asking the question &lt;B&gt;&lt;SPAN&gt;"&lt;I&gt;&lt;SPAN&gt;how many&lt;/SPAN&gt;&lt;/I&gt; threads can I create on a given server?"&lt;/SPAN&gt;&lt;/B&gt; so I can only assume that they are thinking of writing some application that is going to create a &lt;B&gt;&lt;SPAN&gt;large&lt;/SPAN&gt;&lt;/B&gt; and &lt;B&gt;&lt;SPAN&gt;variable&lt;/SPAN&gt;&lt;/B&gt; number of threads, &lt;STRONG&gt;as many as possible&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;That's Thread Happiness right there.&amp;nbsp; Don't do that!&amp;nbsp; It's almost certainly a bad design.&amp;nbsp; Massively multi-threaded applications cause more problems than they solve; they are very difficult to get correct, and even harder to get performant.&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;To actually answer the question, no, there's no way of telling that from the server spec. Why?&amp;nbsp; Because there is nowhere near enough information in the "static" facts about the hardware.&amp;nbsp; Server application threading performance depends on "dynamic" facts like: &lt;BR&gt;&lt;BR&gt;
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;UL type=disc&gt;
&lt;LI&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;What other processes are going to be running?&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;
&lt;LI&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;What are those threads going to be doing?&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;
&lt;LI&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;How much memory do you have free?&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;
&lt;LI&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;How much contention, locking, busy waiting, context switching, blah blah blah, is there going to be?&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;LI&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;What are the performance metrics that will determine when things have gotten too bad.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;So, in short, don't even go there.&amp;nbsp; Come up with a design that uses a small number of threads and tune that.&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Now, you might be wondering "What about real-world server applications which do spin up a variable number of threads then?&amp;nbsp; How do they decide how many is too many?"&lt;BR&gt;&lt;BR&gt;It's quite hard.&amp;nbsp; These things used to be configurable in IIS, but a few years back the IIS team had the realization that (a) you can't expect a human being to figure out what the ideal thread limit is, and (b) the ideal thread limit changes dynamically because of all the factors I mentioned above.&lt;BR&gt;&lt;BR&gt;IIS therefore keeps a relatively small thread pool, and continually monitors its own performance, tweaking the thread pool count, thread priorities, etc, as conditions change.&amp;nbsp; It tries to keep the server well-tuned dynamically.&amp;nbsp; &lt;BR&gt;&lt;BR&gt;This was non-trivial code to write.&amp;nbsp; Though I've done quite a bit of optimization of software that runs in-process with IIS, the details of the IIS thread timing algorithms are way, way beyond my skills.&amp;nbsp; I wouldn't recommend such an approach unless you've got a lot of experience in the field.&amp;nbsp; A huge performance lab with a wide range of server hardware and a dedicated staff of experienced performance testers doesn't hurt either!&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=73366" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Threading/default.aspx">Threading</category></item><item><title>Speeding Can Slow You Down</title><link>http://blogs.msdn.com/ericlippert/archive/2003/12/01/speeding-can-slow-you-down.aspx</link><pubDate>Tue, 02 Dec 2003 01:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:53411</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/53411.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=53411</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I hope all you readers living in the United States had a restful and enjoyable Thanksgiving holiday. I sure did. 
&lt;P&gt;I've been meaning to talk a bit about some of the performance issues you run into when tuning massively multi-threaded applications, like the ASP engine.&amp;nbsp; I'd like to start off by saying that I am by no means an expert in this field, but I have picked up a thing or two from the real experts on the ASP perf team over the years. 
&lt;P&gt;One of the most intriguing things about tuning multi-threaded applications is that &lt;STRONG&gt;making the code faster can slow it down.&lt;/STRONG&gt; How is that possible? It certainly seems counter-intuitive, doesn't it? &lt;/P&gt;
&lt;P&gt;Let me give you an analogy.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Suppose you have an unusual road system in your town.&amp;nbsp; You have a square grid of roads with stoplights at the intersections.&amp;nbsp;But unlike the real world, these are &lt;EM&gt;perfect&lt;/EM&gt; traffic lights -- they are only red if there actually is another car in the intersection.&amp;nbsp;Unlike a normal road, each road goes only one way, and has at most one car on it at a time.&amp;nbsp; Once a car reaches the end of the road, it disappears and a new car may appear at the start. Furthermore, there is a small number of drivers -- typically one or two, but maybe eight or sixteen, but probably not one for every car. The drivers drive a car for a while, then stop it and run to the next car!&amp;nbsp; The drivers are pretty smart -- if their car is stopped at a red stoplight then they'll run to a stopped car that is not at a red stoplight (if one exists) and drive it for a while.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;In our analogy each road represents a &lt;STRONG&gt;thread&lt;/STRONG&gt; and each stoplight represents a &lt;STRONG&gt;mutex&lt;/STRONG&gt;.&amp;nbsp; A mutex is a "mutually exclusive" section of code, also known as a "critical section".&amp;nbsp; Only one thread can be executing in that code at one time. The car represents the position of the &lt;STRONG&gt;instruction counter&lt;/STRONG&gt; in this thread.&amp;nbsp; When the car reaches the end of the road, the task is finished -- the page is served.&amp;nbsp;The drivers represent the &lt;STRONG&gt;processors&lt;/STRONG&gt;, which give attention to one thread at a time and then context switch to another thread.&amp;nbsp; The time spent running from car to car is the time required to perform a thread context switch. &lt;/P&gt;
&lt;P&gt;Now imagine that you want to maximize the throughput of this system -- the total number of cars that reach the end of their road per hour.&amp;nbsp; How do you do it?&amp;nbsp; There are some "obvious" ways to do so: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;hire more drivers (use more processors)&lt;/LI&gt;
&lt;LI&gt;eliminate some stoplights by building overpasses at intersections (eliminate critical sections)&lt;/LI&gt;
&lt;LI&gt;buy faster cars (use faster processors)&lt;/LI&gt;
&lt;LI&gt;make the roads shorter (write pages that require less code)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;You'll note that each of these is either expensive or difficult.&amp;nbsp; Perf isn't easy!&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Now, I said that these are "obvious" ways to solve this problem, and those scare quotes were intentional.&amp;nbsp; Imagine a complex grid of roads with lots of stoplights, a moderate number of cars on the road, and two drivers.&amp;nbsp; It is quite unlikely that cars will spend a lot of time stopped at stoplights -- mostly they'll just breeze right on through.&amp;nbsp; But what happens when you throw another six drivers into the mix? Sure, more cars are being driven at any one time, but that means that the likelihood of congestion at stoplights just went up.&amp;nbsp;&lt;STRONG&gt;Even though there are four times as many drivers, the additional time spent at stoplights means that the perf improvement is less than a factor of four&lt;/STRONG&gt;.&amp;nbsp;We say that such systems are not &lt;EM&gt;scalable&lt;/EM&gt;.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Or consider a moderately congested freeway system with a whole lot of cars, drivers and intersections.&amp;nbsp; Now suppose that you keep the cars, drivers and intersections the same, but you shrink the whole system down to half its previous size. You make all the roads shorter, so that instead of having eight stoplights to the mile, now you've got twenty. Does total throughput get better or worse?&amp;nbsp; In a real traffic system, that would probably make things worse, and it can in web servers as well.&amp;nbsp; The cars spend all their time at intersections waiting for a driver to run over to them. &lt;STRONG&gt;Making code faster sometimes makes performance worse because thread congestion and context switches could be the problem, not total path length. &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Similarly, making the cars faster often doesn't help.&amp;nbsp;In the real world of Seattle traffic, upgrading from my 140-or-so horsepower Miata to a 300 HP BMW isn't going to get me&amp;nbsp;home any faster.&amp;nbsp; Getting a faster processor and shorter program only helps if the "freeway" is clear of traffic. Otherwise, &lt;STRONG&gt;you sit there in your souped-up ultimate driving machine going zero at stoplights like everyone else.&lt;/STRONG&gt;&amp;nbsp;&amp;nbsp;Raw power does not scale in a world with lots of critical sections. &lt;/P&gt;
&lt;P&gt;When perf tuning servers, use the performance monitor to keep a careful eye on not just pages served per second, but on thread switches per second, processor utilization and so on.&amp;nbsp; If you cannot saturate the processor and the number of thread switches is extremely high, then what is&amp;nbsp;likely happening is that the drivers are spending way too much time running from car to car and not enough time actually driving. Clearly that's not good for perf.&amp;nbsp; Tracking down and eliminating critical sections is often the key to improving perf in these scenarios.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=53411" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Threading/default.aspx">Threading</category></item><item><title>Eval is Evil, Part Two</title><link>http://blogs.msdn.com/ericlippert/archive/2003/11/04/53335.aspx</link><pubDate>Tue, 04 Nov 2003 22:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:53335</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/53335.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=53335</wfw:commentRss><description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;?xml:namespace prefix = o ns = 
"urn:schemas-microsoft-com:office:office" /&gt;As
        I promised, more information on why eval is evil.&amp;#160; (We once considered having
        T-shirts printed up that said "Eval is evil!" on one side and "Script happens!" on
        the other, but the PM's never managed to tear themselves away from their web browsing
        long enough to order them.)&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &amp;#160;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" 
/&gt;Incidentally,&amp;#160;a&amp;#160;buddy
        of mine who is one of those senior web developer kinda guys back in 
        &lt;st1:City w:st="on"&gt;
            &lt;st1:place w:st="on"&gt;Waterloo&lt;/st1:place&gt;
        &lt;/st1:City&gt;
        sent me an email yesterday saying "Hello, my name is Robert and I am an evalaholic".&amp;#160;
        People, it wasn't my &lt;em&gt;&lt;span style="FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;intention&lt;/span&gt;&lt;/em&gt; to
        start a twelve step program, but hey, whatever works!&amp;#160;&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;As
        I &lt;a href="http://blogs.gotdotnet.com/ericli/PermaLink.aspx/5f27ae83-ff82-4fea-97db-b6fef3922c3b"&gt;discussed
        the other day&lt;/a&gt;, &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;eval&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; on
        the client is evil because it leads to sloppy, hard-to-debug-and-maintain programs
        that consume huge amounts of memory and run unnecessarily slowly even when performing
        simple tasks.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;But like I said in my &lt;a href="http://blogs.gotdotnet.com/ericli/PermaLink.aspx/bfd7cd56-caf1-47e5-b94a-0c812b1be28e"&gt;performance
        rant&lt;/a&gt;, if it's &lt;strong&gt;&lt;span style="FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;good
        enough&lt;/span&gt;&lt;/strong&gt;, then hey, it's good enough.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Maybe
        you don't &lt;b style="mso-bidi-font-weight: normal"&gt;need&lt;/b&gt; to write maintainable,
        efficient code.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Seriously! Script is
        often used to write programs that are used a couple of times and then thrown away,
        so who cares if they're slow and inelegant?&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;But &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;eval&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; on
        the server is an entirely different beast.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;First
        off, server scenarios are generally a lot more performance sensitive than client scenarios.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;On
        a client, once your code runs faster than a human being can notice the lag, there's
        usually not much point in making it faster.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;But&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;a href="http://blogs.gotdotnet.com/ericli/PermaLink.aspx/ae29f2ce-b06d-47a1-9520-857c350e3988"&gt;as
        I mentioned earlier&lt;/a&gt;, ASP goes to a lot of work to ensure that for a given page,
        the compiler only runs once. An &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;eval&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; defeats
        this optimization by making the compiler run every time the page runs! On a server,
        going from 25 ms to 40 ms to serve a page means going from 40 pages a second to 25
        pages a second, and that can be expensive in real dollar terms.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;But
        that's not the most important reason to eschew &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;eval&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; on
        the server.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Any use of &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;eval&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; (or
        its VBScript cousins &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;&lt;a href="http://blogs.gotdotnet.com/ericli/PermaLink.aspx/4939ad1e-b2d7-436e-a2dc-bd7665d207bf"&gt;Eval&lt;span style="FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;, &lt;/span&gt;Execute&lt;span style="FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; and &lt;/span&gt;ExecuteGlobal&lt;/a&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;)
        is a &lt;b style="mso-bidi-font-weight: normal"&gt;potentially enormous security hole.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/b&gt;&lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;var
        Processor_ProductList;&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;var
        Software_ProductList;&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;var
        HardDisk_ProductList;&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;//
        ...&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;&amp;#160;&amp;#160;CategoryName
        = Request.QueryString("category");&lt;/span&gt;&lt;span style="COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;&amp;#160;&amp;#160;ProductList
        = eval(CategoryName &amp;amp; "_ProductList");&lt;/span&gt;&lt;span style="COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;//
        ...&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;What's
        wrong with this picture?&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;The
        server assumes that the client is not hostile.&lt;/b&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Is
        that a warranted assumption?&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Probably
        not!&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;You know nothing about the client
        that sent the request.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Maybe &lt;b style="mso-bidi-font-weight: normal"&gt;your&lt;/b&gt; client
        page only sends strings like "Processor" and "HardDisk" to the server, but anyone
        can write their own web page that sends 
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;((new
        ActiveXObject('Scripting.FileSystemObject')).DeleteFile('C:\*.*',true)); Processor&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;which
        will cause &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;eval&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; to
        evaluate&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;((new
        ActiveXObject('Scripting.FileSystemObject')).DeleteFile('C:\*.*',true)); Processor_ProductList&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Obviously
        that's a pretty unsophisticated attack.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;The
        attacker can put &lt;a href="http://blogs.gotdotnet.com/ericli/PermaLink.aspx/c40acab4-2215-40c6-999c-2ad2d0d05833"&gt;any
        code in there that they want&lt;/a&gt;, and it will run in the context of the server process.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Hopefully
        the server process is not a highly privileged one, but still, there's vast potential
        for massive harm here just by screwing up the logic on your server.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Never
        trust the input to a server, and try to never use &lt;/span&gt;&lt;/b&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;eval&lt;/span&gt;&lt;/b&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; on
        a server.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;Eval&lt;/span&gt;&lt;/b&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; injection
        makes SQL injection look tame!&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/b&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;To
        try and mitigate these sorts of problems, JScript .NET has some restrictions on its
        implementation of &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;eval&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;,
        but that's a topic for another entry.&lt;/span&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &amp;#160;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
&lt;/body&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=53335" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/JScript/default.aspx">JScript</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category></item><item><title>Global State On Servers Considered Harmful</title><link>http://blogs.msdn.com/ericlippert/archive/2003/10/29/53321.aspx</link><pubDate>Wed, 29 Oct 2003 21:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:53321</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/53321.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=53321</wfw:commentRss><description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;The
        other day I noted that extending the built-in objects in JScript .NET is no longer
        legal in "fast mode".&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;?xml:namespace prefix = o ns = 
"urn:schemas-microsoft-com:office:office" /&gt;Of
        course, this is still legal in "compatibility mode" if you need it, but why did we
        take it out of fast mode?&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;As
        several readers have pointed out, this is actually a kind of compelling feature.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;It's
        nice to be able to add new methods to prototypes:&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;String.prototype.frobnicate
        = function(){/* whatever */}&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;var s1
        = "hello";&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;var s2
        = s1.frobnicate();&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;It
        would be nice to extend the &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;Math&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; object,
        or change the implementation of &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;toLocaleString&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; on &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;Date&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; objects,
        or whatever.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Unfortunately,
        it also breaks ASP.NET, which is the prime reason we developed fast mode in the first
        place.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Ironically, it is not the additional
        compiler optimizations that a static object model enables which motivated this change!&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Rather,
        it is the compilation model of ASP.NET.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;I
        discussed earlier how ASP uses the script engines -- ASP translates the marked-up
        page into a script, which it compiles once and runs every time the page is served
        up.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;ASP.NET's compilation model is similar,
        but somewhat different.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;ASP.NET takes
        the marked-up page and translates it into a &lt;b style="mso-bidi-font-weight: normal"&gt;class&lt;/b&gt; that
        extends a standard page class.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;It compiles
        the derived class once, and then every time the page is served up &lt;b style="mso-bidi-font-weight: normal"&gt;it
        creates a new instance of the class&lt;/b&gt; and calls the &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;Render&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt; method
        on the class.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;So
        what's the difference?&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;The difference
        is that multiple instances of multiple page classes may be running in the same application
        domain.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;In the ASP Classic model, each
        script engine is an entirely independent entity.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;In
        the ASP.NET model, page classes in the same application may run in the same domain,
        and hence can affect each other.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;We don't
        want them to affect each other though -- the information served up by one page should
        not depend on stuff being served up at the same time by other pages.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Now
        I'm sure you see where this is going.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Those
        built-in objects are shared by all instances of all JScript objects in the same application
        domain.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Imagine the chaos if you had
        a page that said:&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;String.prototype.username
        = FetchUserName();&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;String.prototype.appendUserName
        = function() { return this + this.username; };&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;var greeting
        = "hello";&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: #333399; FONT-FAMILY: 'Lucida Console'"&gt;Response.Write(greeting.appendUserName());&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Oh
        dear me.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;We've set up a race condition.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Multiple
        instances of the page class running on multiple threads in the same appdomain might
        all try to change the prototype object at the same time, and the last one is going
        to win.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Suddenly you've got pages that
        serve up the wrong data!&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;That data might
        be highly sensitive, or the race condition may introduce logical errors in the script
        processing -- errors which will be nigh-impossible to reproduce and debug.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;A
        global writable object model in a multi-threaded appdomain where class instances should
        not interact is a recipe for disaster, so we made the global object model read-only
        in this scenario.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;If you need the convenience
        of a writable object model, there is always compatibility mode.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
&lt;/body&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=53321" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/JScript+.NET/default.aspx">JScript .NET</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category></item><item><title>Arrrrr! Cap'n Eric be learnin' about threadin' the harrrrd way</title><link>http://blogs.msdn.com/ericlippert/archive/2003/09/19/arrrrr-cap-n-eric-be-learnin-about-threadin-the-harrrrd-way.aspx</link><pubDate>Fri, 19 Sep 2003 20:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:53054</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/53054.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=53054</wfw:commentRss><description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Arr,
        it be National Talk Like A Pirate Day.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;?xml:namespace prefix = o ns = 
"urn:schemas-microsoft-com:office:office" /&gt;Avast
        ye scurvy dogs!&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;A
        scurvy bilge rat commented on the preceding discussion about putting apartment threaded
        objects in Session scope:&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span class="commentbody"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span class="commentbody"&gt;back in the era of the NT4 Option Pack I wrote a lot of
        code that involved stashing Scripting.Dictionary objects in both session and application
        scope. [...] I forget now which version of the runtime changed the threading model
        they were registered with and broke everything for me.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span class="commentbody"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Shiver
        me timbers!&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;That be my fault.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Sorry
        about that.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;When you create an ActiveX
        object, the COM runtime code checks the registry to see if the object is marked as
        participating in the Apartment, Free or Both threading models.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;(We'll
        go into the difference between Free and Both at another time.)&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Now,
        when I was a young swabbie seven years ago I was given the task of implementing the
        Scripting.Dictionary object, and I didn't yet understand all the stuff I just told
        you maties about threading.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;In one build
        that was released to the public I accidentally marked the dictionary as Both, even
        though it is an apartment object. So when lubbers would put a dictionary into Session
        scope, it would be called by multiple threads at multiple times, in violation of the
        apartment contract.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;As long as there
        were only readers, it was generally OK, but as soon as there were readers and writers,
        it would usually crash and die.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;And
        of course when we corrected the mistake, all those pages went from sometimes-crashing-but-fast
        to not-crashing-but-slow. &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;That
        was my first majorly customer-impacting mistake, and probably the worst I ever personally
        made.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Speaking
        of mistakes, there was another interesting performance mistake in early releases of
        the Scripting.Dictionary object. It uses a very simple hash table for rapid lookup,
        but of course hash tables require that the hash function distribute hashes &lt;strong&gt;broadly&lt;/strong&gt; given
        a &lt;strong&gt;narrow&lt;/strong&gt; distribution of keys.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;I
        screwed up the hash algorithm, and one of the consequences was that hashing on a string
        consisting of five digits was likely to go to a very small number of hash buckets.&amp;#160;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&lt;/span&gt;&lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt;&lt;/span&gt;&amp;#160;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt;We
        discovered all this the day that MSN.COM decided to store EVERY ZIP CODE IN THE UNITED
        STATES in a Scripting.Dictionary object in Session scope!&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Perf
        of MSN.COM went way south, way fast.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;The
        combination of the two mistakes above led the ASP team to write their own string table
        object, that really was Both threaded and blindingly fast. 
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Arr!&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;
    &lt;/p&gt;
&lt;/body&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=53054" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/COM+Programming/default.aspx">COM Programming</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Threading/default.aspx">Threading</category></item><item><title>Why is it a bad idea to put script objects in Session scope?</title><link>http://blogs.msdn.com/ericlippert/archive/2003/09/18/why-is-it-a-bad-idea-to-put-script-objects-in-session-scope.aspx</link><pubDate>Fri, 19 Sep 2003 05:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:53050</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/53050.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=53050</wfw:commentRss><description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;?xml:namespace 
prefix = o ns = "urn:schemas-microsoft-com:office:office" 
/&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Often
        a web site will have a series of related pages requested one after the other by the
        same user.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;As a convenience for the site
        developers, the ASP object model provides a Session object to store server-side state
        for a current user.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;It also has a global
        "Application" object which stores state for an entire virtual root.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Every
        so often some ASP coder out there tries to put a JScript or VBScript object into the
        Session (or Application) object.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Things
        usually start going horribly wrong shortly thereafter -- either terrible performance
        ensues or things just break outright.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Well,
        like Groucho says, if it hurts when you do that, don't do that!&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Understanding
        why this is a bad idea will take us yet deeper into the land of threading models.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="navy" size="3"&gt;&lt;span style="FONT-SIZE: 12pt; COLOR: navy; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Marshaling 
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;I
        mentioned earlier that when you have an apartment threaded object, you need to be
        in the right apartment (thread) if you want to talk to its occupants (object instances).&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;But
        what if you are not?&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;What if you are
        running some code in thread Alpha that &lt;em&gt;really&lt;/em&gt; needs to call a method on an
        object running in thread Beta?&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Fortunately,
        COM provides a mechanism called &lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-WEIGHT: bold; mso-bidi-font-weight: normal"&gt;cross-thread
        marshaling&lt;/span&gt;&lt;/b&gt; to achieve this.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;The
        behind-the-scenes details are not particularly important to our discussion; suffice
        to say that windows messages are involved.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;The
        important thing to know is that when you marshal a call across threads &lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-WEIGHT: bold; mso-bidi-font-weight: normal"&gt;the
        calling thread pauses until the called thread responds&lt;/span&gt;&lt;/b&gt;.&lt;span style="mso-spacerun: yes"&gt;&amp;#160;
        That seems reasonable -- after all, when you call an ordinary function you sort of
        "pause" until the function returns.&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&amp;#160;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="mso-spacerun: yes"&gt;But
        threads are usually busy doing &lt;em&gt;something&lt;/em&gt;.&amp;#160;&amp;#160;I&lt;/span&gt;f the called
        thread is not responding to messages because it is busy doing work of its own then
        the calling thread waits, and waits, and waits...&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;To
        continue with our previous apartment threading analogy, it is rather like each apartment
        has a mailbox.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;If you're in apartment
        Beta and you need someone in apartment Alpha to do something for you, you write up
        a request and hand it to the mailman who in turn sticks it in Alpha's mailslot.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Alpha's
        occupants might be busy doing work and ignoring their mail, or they may have a huge
        stack of mail to get through, or they might get right on it.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;You,
        over in apartment Beta, can't do anything but wait for the mailman to deliver their
        reply.&lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
    &lt;o:p&gt;
        &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
            &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;And
            of course, even if the callee thread is completely responsive and ready to service
            your request, obviously calling across threads is orders of magnitude more expensive
            than calling in-thread.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;An in-thread
            call requires some arguments to be put on the stack and maybe stash a few values in
            registers.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;A cross-thread call gets the
            operating system involved in a comparatively deep and complex way.&lt;o:p&gt;&lt;/o:p&gt;
            &lt;/span&gt;&lt;/font&gt;
        &lt;/p&gt;
        &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&amp;#160;
        &lt;/p&gt;&lt;/o:p&gt;
    &lt;/span&gt;&lt;/font&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="navy" size="3"&gt;&lt;span style="FONT-SIZE: 12pt; COLOR: navy; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Performance
        Woes&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Now
        you have enough information to figure out why putting script objects in Session scope
        is a bad idea as far as performance is concerned.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&amp;#160;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt;Each
        ASP page is running on its own thread from the thread pool.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;The
        thread that reads the object from session state will likely not be the thread that
        put the object there, but the script object is apartment threaded.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;That
        means that essentially any page that accesses that session object must wait its turn
        for all other pages using that session object to finish up, because &lt;strong&gt;the marshaling
        code blocks the calling thread until the callee is available.&lt;/strong&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt; &lt;/span&gt;You
        end up with a whole lot of blocking threads, and blocking threads are not fast.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Application
        scope is even worse -- if you put a script object in Application scope then &lt;strong&gt;every
        page in the entire vroot that accesses the Application object must wait its turn&lt;/strong&gt; for
        the original thread to be free.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;You've
        effectively single-threaded your web server.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="navy" size="3"&gt;&lt;span style="FONT-SIZE: 12pt; COLOR: navy; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Script
        Engine Of The Living Dead&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;But
        it gets worse.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Remember, when the page
        is done being served up, the engine is torn down.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;The
        compiled state remains, but the runtime state is thrown away.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;So
        suppose you have a JScript object sitting in the Session object, and the page that
        put it there was destroyed a few microseconds ago and the engine put back into the
        engine pool.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Now on another page in the
        same session you try to fetch the JScript object and call a method on it.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Where's
        the runtime state associated with that object?&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;It's
        gone, dude.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;When
        the script engine is torn down after the original page is served, the teardown code
        detects that there are existing objects that are owned by external callers.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;The
        script engine can't destroy these objects, otherwise the caller would crash when the
        caller tried to destroy them later.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;That's
        a fundamental rule of COM -- you can't destroy an object to which someone holds a
        reference.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&amp;#160;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt;But
        we know that the object is going to be useless, so what we do is tell the object "the
        engine you require for life is going away.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Throw
        away everything you own and become a zombie."&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;
        &lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;These
        zombie objects look like script objects, but when you actually try to do something
        to them -- call a method, fetch a property, whatever -- they don't actually do anything.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;They
        can't -- all the infrastructure they need to live is gone, but they can't die.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Basically
        they wander the night in ghostly torment until they are freed by whatever code is
        holding the reference.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;So
        not only are those script objects sitting in Session state wrecking your performance,
        they're not even &lt;em&gt;useful&lt;/em&gt; for anything once the original page goes away.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Incidentally,
        Windows Script Components each have their own engine which stays alive as long as
        they do, so WSC's are not affected by the zombie issue.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;They
        are still apartment threaded though.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="navy" size="3"&gt;&lt;span style="FONT-SIZE: 12pt; COLOR: navy; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;Arrays
        Are Almost As Bad&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;JScript
        arrays are objects, so everything said above applies to them.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;VBScript
        arrays are not objects (more on the differences between these two kinds of arrays
        later) but even still, you shouldn't put them in Session scope either.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Though
        they do not suffer from the threading problems or the lifetime problems mentioned
        above, arrays are stored into and passed out of Session scope using our old friend
        copy-in-copy-out semantics.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;That means
        that &lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-WEIGHT: bold; mso-bidi-font-weight: normal"&gt;every
        single time &lt;/span&gt;&lt;/b&gt;you index into an array in Session scope, &lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-WEIGHT: bold; mso-bidi-font-weight: normal"&gt;a
        copy of the array is made first&lt;/span&gt;&lt;/b&gt;.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;If
        that array is big, that's a big performance problem.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&amp;#160;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt;Why
        do we do copy-in-copy-out?&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;i style="mso-bidi-font-style: normal"&gt;&lt;span style="FONT-STYLE: italic; mso-bidi-font-style: normal"&gt;Because&lt;/span&gt;&lt;/i&gt; arrays
        are not marshaled!&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;We return to the fundamental
        problem: what if two pages tried to read and write the array in the Session object
        at the same time?&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;The memory could be
        corrupted.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;We really don't have any good
        way to synchronize access to the array, so instead we simply make a complete copy
        of it every time someone tries to read or write it.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;This
        is extremely expensive, but it keeps the server heap from being corrupted.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;A
        corrupted web server heap can ruin your whole day.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;My
        advice is to not even go there.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;strong&gt;Don’t
        put information into Session scope unless you absolutely have to.&lt;/strong&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt; &lt;/span&gt;If
        you must, put in strings.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;There are lots
        of ways to store arrays or objects as strings and reconstitute them as needed.&lt;o:p&gt;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
    &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;
        &lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: purple; FONT-FAMILY: 'Lucida Sans Unicode'; mso-bidi-font-family: 'Times New Roman'"&gt;
        &lt;o:p&gt;&amp;#160;&lt;/o:p&gt;
        &lt;/span&gt;&lt;/font&gt;
    &lt;/p&gt;
&lt;/body&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=53050" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/JScript/default.aspx">JScript</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/VBScript/default.aspx">VBScript</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/COM+Programming/default.aspx">COM Programming</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Threading/default.aspx">Threading</category></item><item><title>How does Active Server Pages use the script engines?</title><link>http://blogs.msdn.com/ericlippert/archive/2003/09/18/how-does-active-server-pages-use-the-script-engines.aspx</link><pubDate>Fri, 19 Sep 2003 00:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:53046</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/53046.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=53046</wfw:commentRss><description>&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;It's always struck me as a little bit odd that Active Server Pages, a web server, encourages developers to use VBScript and JScript to write server-side scripts.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;I mean, the whole point of a web server is that it produces complex strings (web pages are just strings of HTML after all) as blindingly fast as possible, on demand.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;"Blindingly fast" and "script language" do not really go together, compared to, say, C. 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;My opinions -- and you'd better believe I have plenty of strong ones! -- on performance characteristics of the script engines will certainly come back in &lt;A href="http://blogs.msdn.com/ericlippert/category/2717.aspx?Show=All"&gt;future posts&lt;/A&gt;.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;But for now I want to talk a little bit about what features we added to the script engines to make them work as well as they do for ASP. 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;One of the ways you make a server fast is by caching everything you possibly can cache.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;For example, suppose you need to do a job on a separate thread.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;You'd probably create a thread, do some work on the thread, and throw it away when you're done.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;OK, now suppose you need to do a million jobs but never more than, say, three at a time. Creating and destroying those million threads is potentially going to be a not-insignificant amount of the total processor time spent.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;You'd be better off &lt;B&gt;&lt;SPAN&gt;creating three threads and re-using them as necessary&lt;/SPAN&gt;&lt;/B&gt;. &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;This strategy is called &amp;#8220;thread pooling&amp;#8221;, and ASP certainly uses it.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;(UPDATE: I've written a follow-up article on &lt;A href="http://blogs.msdn.com/ericlippert/archive/2004/02/15/73366.aspx"&gt;Thread Happiness Disease&lt;/A&gt;.)&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;ASP caches a lot more than that though.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;It also pools script engines and caches compiled state.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Let me explain with an example. 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Suppose a request comes in for this page, time.asp:&lt;/SPAN&gt;&lt;/FONT&gt; 
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;&amp;lt;html&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399&gt;&lt;SPAN&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;&amp;lt;% Response.write Now() %&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399&gt;&lt;SPAN&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;&amp;lt;/html&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399&gt;&lt;SPAN&gt; 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Suppose further that this is the first-ever request for this page since the server was started.&amp;nbsp; 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;The thing above isn&amp;#8217;t a legal script, so ASP parses out the non-script blocks and stores them in the Response object.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;It then generates a real script that looks something like 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;Response.WriteBlock 0&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399&gt;&lt;SPAN&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;Response.Write Now()&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399&gt;&lt;SPAN&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;Response.WriteBlock 1&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt; 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;ASP also has a pool of created-but-not-initialized script engines sitting around.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;I said in my last post that &lt;STRONG&gt;when the script engines are not initialized they can be called on any thread,&lt;/STRONG&gt; so it does not matter that these engines were not created on whatever thread happened to be pulled out of the thread pool.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;SPAN&gt;&lt;/SPAN&gt;ASP initializes the engine on the current thread and passes in the script code above.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;The script engine compiles the script, runs it, and the ASP object model sends the resulting string off to the client. 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;The script engine then gets uninitialized, but does not throw away its compiled state.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;The compiled state &amp;#8211; the proprietary bytecode form of the language &amp;#8211; is maintained in memory because the second time someone asks for that page, ASP do not want to have to go through all the time and expense of translating the page to script and compiling the script to bytecode. 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;The thread and the now-uninitialized engine go back to their respective pools. 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Now suppose a second request comes in for time.asp.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;This time ASP pulls a thread out of the thread pool, notices that it has an engine with the compiled state just sitting there, attaches the engine to the thread, and runs the script again.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;No time is spent creating the thread, creating the script engine, translating the page to code or compiling the script to bytecode. 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Suppose further that in the few milliseconds that ASP is running this script, a third request comes in for this page.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Then what happens?&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;There are two obvious possibilities: 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;SPAN&gt;1)&lt;FONT face="Times New Roman" size=1&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Wait for the current engine to finish, and start it right back up again when it is done.&lt;SPAN&gt;&amp;nbsp; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;SPAN&gt;2)&lt;FONT face="Times New Roman" size=1&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Fetch a new engine from the engine pool and start over &amp;#8211; translate the page to script, compile, run. 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;The trouble is, both of those are potentially slow.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;The first in particular could be extremely slow. We needed a third option. 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;In my previous post I discussed &lt;A href="http://blogs.msdn.com/ericlippert/archive/2003/09/18/53041.aspx"&gt;the sorts of trouble you can get into with multi-threading&lt;/A&gt;.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Note that the problem I described happens because two threads tried to both read &lt;I&gt;&lt;SPAN&gt;and&lt;/SPAN&gt;&lt;/I&gt; write a particular value.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;If the value was read-only, then obviously there would not have been a problem.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;You can read a read-only value from as many threads as you want! 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Hey, once the script engine compiles a script into bytecode, that bytecode is read-only.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;It&amp;#8217;s never going to change again.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;This means that two script engines on two different threads can share bytecode! 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;I lied earlier when I said that &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;InterruptScriptThread&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt; was the only exception to our weird threading model.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;We have another exception &amp;#8211; at any time, you can call &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;&lt;SPAN&gt;Clone&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt; from any thread.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;This takes an existing script engine and gives you a new script engine with exactly the same compiled state, but able to run on a different thread. Each engine maintains its own runtime state &amp;#8211; variable values, etc &amp;#8211; but the compiled state is shared. 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;So in this scenario, ASP &lt;B&gt;&lt;SPAN&gt;clones the running engine onto another thread and then runs the new engine concurrently&lt;/SPAN&gt;&lt;/B&gt;.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;This is&amp;nbsp;&lt;EM&gt;somewhat&lt;/EM&gt; expensive &amp;#8211; it has to create a new engine, after all &amp;#8211; but is &lt;EM&gt;much cheaper&lt;/EM&gt; than compiling up all that state again. 
&lt;P&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;Of course, ASP is much more complicated than that quick sketch.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;What I&amp;#8217;m getting at here is that there actually is some rhyme and reason to our bizarre-seeming choices of threading model.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;&lt;SPAN&gt;&lt;/SPAN&gt;The script engine design was driven by the need to solve a very specific set of very disparate problems.&amp;nbsp; Without knowing what the problems were, the resulting design looks kind of random.&amp;nbsp; But once you know the history, well, I guess it looks a little &lt;EM&gt;less&lt;/EM&gt; random.&lt;/SPAN&gt;&lt;/FONT&gt; &lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;SPAN&gt;UPDATEL: I've written&amp;nbsp;a follow-up article on &lt;A href="http://blogs.msdn.com/ericlippert/archive/2004/02/19/76438.aspx"&gt;how the ASP compilation model is affected by having&amp;nbsp;multiple languages per page&lt;/A&gt;.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=53046" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Threading/default.aspx">Threading</category></item></channel></rss>