<?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>Thomas Marquardt's Blog</title><link>http://blogs.msdn.com/tmarq/default.aspx</link><description /><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Correct use of System.Web.HttpResponse.Redirect</title><link>http://blogs.msdn.com/tmarq/archive/2009/06/25/correct-use-of-system-web-httpresponse-redirect.aspx</link><pubDate>Thu, 25 Jun 2009 20:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9803956</guid><dc:creator>tmarq</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/9803956.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=9803956</wfw:commentRss><description>&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;Try very, very&amp;nbsp;hard to avoid using Response.Redirect(url), instead, use Response.Redirect(url, &lt;STRONG&gt;false&lt;/STRONG&gt;).&amp;nbsp; Response.Redirect(url), after writing a 302 redirect response to the response buffers, calls Response.End.&amp;nbsp; This is very expensive.&amp;nbsp; The alternative, Response.Redirect(url, &lt;STRONG&gt;false&lt;/STRONG&gt;) is fast, but unlike Response.Redirect(url), the lines of code which&amp;nbsp;follow the call to Response.Redirect(url, &lt;STRONG&gt;false&lt;/STRONG&gt;) will be executed.&amp;nbsp; More on this later, but first, let me tell you about the horrors of Response.End.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;Response.End is a terrible method.&amp;nbsp; It was added in ASP.NET 1.0 for compatibility with classic ASP.&amp;nbsp;&amp;nbsp;In classic ASP, this method terminated script processing, so that the lines of script that followed this call never executed.&amp;nbsp; How do you simulate that in managed code?&amp;nbsp; The only way is to abort the thread, which raises a ThreadAbortException and&amp;nbsp;is&amp;nbsp;outrageously expensive.&amp;nbsp; Normally, that's exactly what Response.End does in ASP.NET, however, if it is called from within an asynchronous handler/module (a.k.a. an asynchronous pipeline event), it will instead perform a synchronous flush of the response buffers (can you say expensive?) and then complete the request by calling Context.ApplicationInstance.CompleteRequest().&amp;nbsp; Either way, whether you're calling it from a synchronous handler/module or an asynchronous handler/module, Response.End is horribly expensive, and you should avoid it.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;Ok, so what if&amp;nbsp;you don't want the lines of code to execute after&amp;nbsp;you redirect?&amp;nbsp; Well, one way to accomplish this is to call HttpApplication.CompleteRequest(), which is accessible from the HttpContext. e.g., call calling Context.ApplicationInstance.CompleteRequest().&amp;nbsp; It's not the same as aborting the thread, which truly does prevent all subsequent lines of code form running.&amp;nbsp; The lines of code that follow the call to CompleteRequest() will execute, but as soon as the current page or module that calls this completes, the pipeline will jump ahead to the EndRequest event, thereby short circuiting the pipeline.&amp;nbsp; This is usually all you need.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;So to summarize...&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;STRONG&gt;BAD&lt;/STRONG&gt;:&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;
&lt;P style="MARGIN: 0in 0in 0pt 0.5in" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;Response.Redirect(url);&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&lt;STRONG&gt;GOOD&lt;/STRONG&gt;:&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;o:p&gt;
&lt;P style="MARGIN: 0in 0in 0pt 0.5in" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;Response.Redirect(url, &lt;B&gt;false&lt;/B&gt;);&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt 0.5in" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;Context.ApplicationInstance.&lt;B&gt;CompleteRequest()&lt;/B&gt;;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;But before I put my pen away, there's one more common practice I've seen that people should be aware of .&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;In classic mode, calling &lt;STRONG&gt;Response.Redirect(url)&lt;/STRONG&gt; from Application_Error &lt;STRONG&gt;without calling Server.ClearError&lt;/STRONG&gt; is doubly expensive.&amp;nbsp; It causes three exceptions to be thrown, and then either raises a ThreadAbortException or does a synchronous flush and completes the response.&amp;nbsp; And in integrated mode, calling Response.Redirect(url) from Application_Error &lt;STRONG&gt;without calling Server.ClearError&lt;/STRONG&gt; does not even work.&amp;nbsp; Instead, you should use the following code, which&amp;nbsp;performs&amp;nbsp;well in both classic mode and integrated mode.&amp;nbsp; If you’re going to redirect from Application_Error, you should do it the following way:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&lt;STRONG&gt;GOOD&lt;/STRONG&gt;:&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt 0.5in" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;void Application_Error(object sender, EventArgs e)&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt 0.5in" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt 0.5in" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Server.&lt;B&gt;ClearError()&lt;/B&gt;;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt 0.5in" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.Redirect(url, &lt;B&gt;false&lt;/B&gt;);&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt 0.5in" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Context.ApplicationInstance.&lt;B&gt;CompleteRequest()&lt;/B&gt;;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt 0.5in" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;The behavior difference between classic and integrated mode with respect to calling Redirect from Application_Error without calling Server.ClearError is just due to the different environments.&amp;nbsp; You might notice that with a default 3.5 install, if you remove the ASP.NET ScriptModule from the IIS &amp;lt;modules&amp;gt; section, you're suddenly able to call Redirect from Application_Error without calling Server.ClearError.&amp;nbsp; ScriptModule registers a PreSendRequestHeaders handler.&amp;nbsp; In integrated mode, the PreSendRequestHeaders event is implemented differently.&amp;nbsp; As a result, in integrated mode, the exception will be rendered if you try to redirect without clearing the error from Application_Error.&amp;nbsp; I’ve attached a sample that demonstrates the difference between the two pipelines.&amp;nbsp; This sample will demonstrate the difference regardless of whether or not ScriptModule is installed.&amp;nbsp; Just request default.aspx.&amp;nbsp; Then change the value of demonstratePipelineDifference in global.asax, and request default.aspx again.&amp;nbsp; Do this in both classic mode and integrated mode, and observe the behavior.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;Thanks,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Tahoma','sans-serif'; FONT-SIZE: 10pt"&gt;Thomas&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9803956" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/tmarq/attachment/9803956.ashx" length="739" type="application/x-zip-compressed" /></item><item><title>Obtaining more information from an HttpException</title><link>http://blogs.msdn.com/tmarq/archive/2009/03/10/obtaining-more-information-from-an-httpexception.aspx</link><pubDate>Tue, 10 Mar 2009 23:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9469736</guid><dc:creator>tmarq</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/9469736.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=9469736</wfw:commentRss><description>&lt;P&gt;ASP.NET throws HttpException for numerous types of errors, making it difficult to determine exactly what went wrong programmatically. You can parse the error message, but the message can be localized,&amp;nbsp;and therefore&amp;nbsp;parsing&amp;nbsp;it can be&amp;nbsp;non-trivial.&amp;nbsp; There is, however, a way that you can identify a few specific types of errors.&lt;/P&gt;
&lt;P&gt;In v2.0 there is an internal&amp;nbsp;property on HttpException named WebEventCode&amp;nbsp;that returns an int.&amp;nbsp; This value contains additional information which you can use to determine the type of error.&amp;nbsp; Because it is internal you will have to use private reflection to get the value, but the property has been made public in v4.0.&amp;nbsp; Below I've listed the meaning of several of the possible values of this property:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;If the HttpException&amp;nbsp;is because the request timed out ("Request timed out."), the value will be&amp;nbsp;&amp;nbsp;System.Web.Management.&lt;STRONG&gt;WebEventCodes.RuntimeErrorRequestAbort&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;If it's because the client posted too much data ("Maximum request length exceeded."), the value will be &lt;STRONG&gt;WebEventCodes.RuntimeErrorPostTooLarge&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;If it's&amp;nbsp;caused by a ViewState error, the value will be &lt;STRONG&gt;WebEventCodes.RuntimeErrorViewStateFailure&lt;/STRONG&gt;.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Again, this property has been made public in v4.0, but for v2.0, you'll have to use private reflection to access it.&lt;/P&gt;
&lt;P&gt;-Thomas&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9469736" width="1" height="1"&gt;</description></item><item><title>Using IIS 7.0 Dynamic Compression with ASP.NET Output Cache </title><link>http://blogs.msdn.com/tmarq/archive/2008/08/27/using-iis-7-0-dynamic-compression-with-asp-net-output-cache.aspx</link><pubDate>Wed, 27 Aug 2008 22:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8901188</guid><dc:creator>tmarq</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/8901188.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=8901188</wfw:commentRss><description>&lt;P&gt;This post&amp;nbsp;discusses an efficient way to compress content served by the ASP.NET output cache.&amp;nbsp;&amp;nbsp;In .NET Framework v2.0 SP1, included with Windows Server 2008, the ASP.NET Output Cache includes a new feature that allows cached responses to vary by the response's &lt;A class="" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11" mce_href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11"&gt;Content-Encoding&lt;/A&gt; header.&amp;nbsp; And IIS 7.0 has efficient compression algorithms for gzip and deflate.&amp;nbsp; Put the two together, and you can efficiently compress responses once, and serve them from the cache many times.&lt;/P&gt;
&lt;P&gt;Here's how you can do this on Windows Server 2008:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;1.&lt;/STRONG&gt;&amp;nbsp; If you haven't already, install the Dynamic Content Compression role for IIS 7.0 using the Server Manager.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;2.&lt;/STRONG&gt;&amp;nbsp; Step 1 will add the &lt;STRONG&gt;&amp;lt;httpCompression&amp;gt;&lt;/STRONG&gt; configuration section to applicationHost.config.&amp;nbsp; Note that only gzip compression is supported by default.&amp;nbsp; However, deflate is also implemented in gzip.dll, so if you add the following to the &lt;STRONG&gt;&amp;lt;httpCompression&amp;gt;&lt;/STRONG&gt; configuration section, you'll also have deflate enabled:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&amp;lt;scheme name="deflate" dll="%Windir%\system32\inetsrv\gzip.dll" /&amp;gt;&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;3.&lt;/STRONG&gt; Create an application with an ASPX page like the one below.&amp;nbsp; This example page will cache at most 3 responses, one that is gzip compressed, one deflate compressed, and one that is a normal (uncompressed) response.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&amp;lt;%@ Page language="C#" %&amp;gt;&lt;BR&gt;&amp;lt;%@ OutputCache duration="600" varyByParam="None" varyByContentEncoding=&lt;STRONG&gt;"gzip;deflate"&lt;/STRONG&gt; %&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;lt;script runat="server"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void Page_Load() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Request.ServerVariables[&lt;STRONG&gt;"IIS_EnableDynamicCompression"&lt;/STRONG&gt;] = &lt;STRONG&gt;"1"&lt;/STRONG&gt;; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.Write(DateTime.Now);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;lt;/script&amp;gt;&amp;nbsp;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;4.&lt;/STRONG&gt;&amp;nbsp; You must enable the IIS 7.0 "dynamic compression before cache" feature.&amp;nbsp; You can do this by adding the following to your application's web.config file.&amp;nbsp; &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&amp;lt;system.webServer&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;urlCompression doDynamicCompression=&lt;STRONG&gt;"false"&lt;/STRONG&gt; dynamicCompressionBeforeCache=&lt;STRONG&gt;"true"&lt;/STRONG&gt; /&amp;gt;&lt;BR&gt;&amp;lt;/system.webServer&amp;gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;Note that in Step 4, doDynamicCompression=&lt;STRONG&gt;"false"&lt;/STRONG&gt;.&amp;nbsp; If you set this to &lt;STRONG&gt;"true"&lt;/STRONG&gt;, all responses will be compressed.&amp;nbsp; That is, pages that are not using the output cache, as well as pages that are using the output cache (but may not be using varyByContentEncoding) will be compressed.&amp;nbsp;&amp;nbsp;Our example sets doDynamicCompression to &lt;STRONG&gt;"false"&lt;/STRONG&gt; in configuration, but then uses the server variable &lt;STRONG&gt;"IIS_EnableDynamicCompression"&lt;/STRONG&gt; to enable it for a specific page.&amp;nbsp; Alternatively, you could use configuration and &amp;lt;location path=""&amp;gt; to limit the scope of compression.&lt;/P&gt;
&lt;P mce_keep="true"&gt;So how does this work?&amp;nbsp; When a request is sent to the server, it may or may not include an &lt;A class="" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3" mce_href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3"&gt;Accept-Encoding&lt;/A&gt; header, indicating one or more acceptable encodings.&amp;nbsp; For example, Internet Explorer sends "Accept-Encoding: gzip, deflate".&amp;nbsp; When the ASP.NET Output Cache receives the request, if the page is using the VaryByContentEncoding feature,&amp;nbsp;ASP.NET will check if any of the encodings specified by VaryByContentEncoding match the request's Accept-Encoding header.&amp;nbsp; If there is a match, ASP.NET will see if that response is in the cache and serve it.&amp;nbsp; If it's not cached, ASP.NET will render the response and the IIS 7.0 DynamicCompressionModule, which runs during &lt;A class="" href="http://blogs.msdn.com/tmarq/archive/2007/08/30/iis-7-0-asp-net-pipelines-modules-handlers-and-preconditions.aspx" mce_href="http://blogs.msdn.com/tmarq/archive/2007/08/30/iis-7-0-asp-net-pipelines-modules-handlers-and-preconditions.aspx"&gt;RQ_RELEASE_REQUEST_STATE&lt;/A&gt;, will encode the response according to the request's Accept-Encoding header, and it will set the response's Content-Encoding header.&amp;nbsp; For the example request, the response header will be set to "Content-Encoding: gzip".&amp;nbsp; When the ASP.NET OutputCacheModule runs during &lt;A class="" href="http://blogs.msdn.com/tmarq/archive/2007/08/30/iis-7-0-asp-net-pipelines-modules-handlers-and-preconditions.aspx" mce_href="http://blogs.msdn.com/tmarq/archive/2007/08/30/iis-7-0-asp-net-pipelines-modules-handlers-and-preconditions.aspx"&gt;RQ_UPDATE_REQUEST_CACHE&lt;/A&gt;, it will check to see if the Content-Encoding header has been set, and&amp;nbsp;if specified in VaryByContentEncoding, it will cache the response according to that encoding.&amp;nbsp; If the Content-Encoding is not set, the response can be cached as the identity.&lt;/P&gt;
&lt;P&gt;This ASP.NET Output Cache feature can be used via the &amp;lt;%@ OutputCache varyByContentEncoding= %&amp;gt; page directive, programmatically via HttpCachePolicy.VaryByContentEncodings, or via configuration outputCacheProfiles&amp;gt;&amp;lt;add varyByContentEncoding=””&amp;gt;&amp;lt;/outputCacheProfiles&amp;gt;.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Here are a few of the implementation details:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;The value of the VaryByContentEncoding property is the name of an encoding, or a semi-colon separated list of encodings (e.g. "gzip", "gzip; deflate; compress").&amp;nbsp; &lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;The identity, or plain text, is a special case.&amp;nbsp; You can consider it to be implicitly included in the value of VaryByContentEncoding.&amp;nbsp; E.g., if you specify varyByContentEncoding="gzip", ASP.NET will cache at most two responses, gzip and the identity.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;A response&amp;nbsp;can be cached only if&amp;nbsp;the value of its&amp;nbsp;Content-Encoding header is&amp;nbsp;included in VaryByContentEncoding; except for the identity, which is a special case.&amp;nbsp; If the response does not have a Content-Encoding header, it can be cached as the identity.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;A response will be served from the cache if it&amp;nbsp;has an&amp;nbsp;acceptable encoding according to &lt;A class="" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3" mce_href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3"&gt;RFC 2616, Section 14.3&lt;/A&gt;&amp;nbsp;(qvalues are supported).&amp;nbsp;However, even if the identity is available in the cache, if an acceptable encoding is found in VaryByContentEncoding, but that encoding has not yet been cached, ASP.NET will allow the page to render so that a response for that encoding may be cached.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;If the value of the Content-Encoding response header is not in the list, the response is not cacheable. If the Content-Encoding response header is in the list, the response is cacheable (assuming nothing else in its cache policy prevents it from being cached). &lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;If the Content-Encoding response header is not set, the response may be cached as the identity (again, assuming nothing else in its cache policy prevents it from being cached).&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;If the request's Accept-Encoding doesn't match any cached responses, and is not listed in VaryByContentEncoding,&amp;nbsp;and the identity is available in the cache, then the response served will be the identity.&amp;nbsp;&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;Regards,&lt;BR&gt;Thomas&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8901188" width="1" height="1"&gt;</description></item><item><title>ASP.NET Cache can notify you before an entry is removed</title><link>http://blogs.msdn.com/tmarq/archive/2008/07/22/asp-net-cache-can-notify-you-before-an-entry-is-removed.aspx</link><pubDate>Tue, 22 Jul 2008 19:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8764523</guid><dc:creator>tmarq</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/8764523.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=8764523</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;.NET Framework v2.0 SP2, which will be included with .NET Framework v3.5 SP1, is scheduled to release this summer.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This release contains a long awaited ASP.NET Cache feature, which will notify you when an entry becomes invalid and leave the stale entry in the cache while you generate a replacement in the background.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Therefore, requests are not blocked attempting to access the cache entry while it is being updated, and the update is done by a single thread.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Here's the specification:&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;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;U&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;A new Cache.Insert overload&lt;/SPAN&gt;&lt;/U&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;void Cache.Insert( String key,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;Object expensiveObject,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;CacheDependency dependencies,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;DateTime absoluteExpiration,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;TimeSpan slidingExpiration,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;CacheItemUpdateCallback onUpdateCallback &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &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 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;This method inserts an object into the cache, with optional dependencies and expiration policy, and a callback that is invoked before the entry is removed.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Objects inserted into the cache with this method should be expensive to generate.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;You should not use this method for objects that are inexpensive to generate, because there is overhead in the implementation.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;When the callback is invoked, the application developer should generate a new object, with new dependencies and expiration policy, and return it via the callback’s out parameters.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The stale cache entry will be accessible while the callback is executing and the replacement object is generated.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Cache entries inserted by this method are not subject to eviction by the cache memory manager.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;These objects only become invalid when they expire or a dependency changes, and therefore these objects &lt;B style="mso-bidi-font-weight: normal"&gt;MUST&lt;/B&gt; have some form of invalidation (i.e., it is not possible to insert the entry with a null dependency, NoAbsoluteExpiration, and NoSlidingExpriation).&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;U&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;A new update callback&lt;/SPAN&gt;&lt;/U&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;void CacheItemUpdateCallback( String key,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;CacheItemUpdateReason reason,&lt;BR&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;out Object expensiveObject,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;out CacheDependency dependencies,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;out DateTime absoluteExpiration,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;out TimeSpan slidingExpiration &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;When the cache entry becomes invalid, ASP.NET invokes this callback, allowing the application developer to generate a replacement cache entry.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The developer is passed only two pieces of information:&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;the key for the cache entry, and an enum value indicating why the entry is invalid.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The rest of the arguments to the callback are output-only parameters, allowing references to the newly generated object, dependencies, and expiration policy to be passed back and subsequently inserted into the cache by 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 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&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 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Do not modify the existing cache entry.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The stale cache entry is still alive and potentially being used by other threads.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It is not included in the callback arguments in order to minimize the likelihood of a developer accidentally updating portions of the cache entry.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Although this pitfall exists today in the cache API (e.g. a cache entry could be modified in a non-thread-safe manner by an ASP.NET developer), we think leaving the cached value out of the callback arguments will reduce the likelihood of a developer stumbling into this. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;To remove the cache entry, simply set the argument &lt;I style="mso-bidi-font-style: normal"&gt;expensiveObject&lt;/I&gt; to null.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Otherwise, set it to the newly generated replacement object.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The developer &lt;B style="mso-bidi-font-weight: normal"&gt;MUST&lt;/B&gt; also specify expiration and/or dependency information using the other out parameters.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;As stated above, the cache entry is not subject to eviction by the cache memory manager, and therefore must have some form of invalidation.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It is an error to pass back a non-null value for &lt;I style="mso-bidi-font-style: normal"&gt;expensiveObject&lt;/I&gt; while setting &lt;I style="mso-bidi-font-style: normal"&gt;dependencies&lt;/I&gt; to null, &lt;I style="mso-bidi-font-style: normal"&gt;absoluteExpiration&lt;/I&gt; to NoAbsolteExpiration, and &lt;I style="mso-bidi-font-style: normal"&gt;slidingExpriation&lt;/I&gt; to NoSlidingExpiration.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The cache entry will be removed if this occurs.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;If the developer’s callback throws an exception, ASP.NET will suppress the exception and remove the cache entry.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The exception needs to be suppressed because cache item updates occur in the background where there is no call path for routing the exception back to user code.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The cache entry&amp;nbsp;is removed because without a new cache value, ASP.NET has no way of knowing what the correct behavior is for updating the cached item.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&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 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;The update callback will not be called if the cached item was explicitly removed via a call to Cache.Remove, or a call to Cache.Insert (Insert removes a pre-existing entry).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;These operations indicate the developer’s intent to remove the item, so the update callback will not be triggered. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;U&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;A new update reason enumeration&lt;/SPAN&gt;&lt;/U&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;public enum CacheItemUpdateReason {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;// The item was removed from the cache because either &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;// the absolute or sliding expiration interval expired.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Expired = 1,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;// The item was removed from the cache because an &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;// associated cache dependency was changed.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;DependencyChanged = 2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Unlike the CacheItemRemovedReason enumeration, the update reason enumeration does not include values for Removed (see explanation above) or Underused (as mentioned above, the cache entry is not subject to eviction by the cache memory manager).&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Regards,&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Thomas&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8764523" width="1" height="1"&gt;</description></item><item><title>If you allocate from the Large Object Heap each time an ASPX page is requested, your performance will be dismal.</title><link>http://blogs.msdn.com/tmarq/archive/2008/04/29/if-you-allocate-from-the-large-object-heap-each-time-an-aspx-page-is-requested-your-performance-will-be-dismal.aspx</link><pubDate>Tue, 29 Apr 2008 23:12:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8439140</guid><dc:creator>tmarq</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/8439140.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=8439140</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT face="Times New Roman" size=3&gt;I've been giving this advice for years internally, and the problem pops up way too often.&amp;nbsp; I'm sure it will be addressed eventually, in a future version of the CLR, but for now, every released version of the CLR has this problem.&amp;nbsp;&amp;nbsp;If you allocate objects larger than 85000 bytes, they will be allocated in the Large Object Heap (LOH).&amp;nbsp; The LOH is not compacted and collection only occurs after a full collection (so gen 2 must be collected in order to&amp;nbsp;collect an object in the LOH).&amp;nbsp; Short-lived and frequent LOH allocations will kill the performance of your application.&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT face="Times New Roman" size=3&gt;As an example, if you allocate from the LOH each time an ASPX page is requested, your performance will be dismal.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT face="Times New Roman" size=3&gt;To know if you’re allocating from the Large Object Heap (LOH), you can use this break point on v2.0 on a multi-proc box, where the server GC is enabled by default: &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in"&gt;&lt;FONT face="Times New Roman" size=3&gt;bp mscorwks!SVR::gc_heap::allocate_large_object ".echo size=; ? poi(@esp+4); k12; gc"&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT face="Times New Roman" size=3&gt;If you want to get fancy, the following will attach ntsd to w3wp.exe, disable break on first chance exceptions, and trace the calls to allocate_large_object to %SYSTEMDRIVE%\NTSD.log&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in"&gt;&lt;FONT face="Times New Roman" size=3&gt;ntsd.exe -y %WINDIR%\symbols;srv*%WINDIR%\Symbols*http://msdl.microsoft.com/download/symbols -xd * -c "bp mscorwks!SVR::gc_heap::allocate_large_object \".echo size=; ? poi(@esp+4); k12; gc\"; g" -G -logo %SYSTEMDRIVE%\NTSD.log -pn w3wp.exe&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in"&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;You can also deterimine if you're allocating from the LOH by profiling a request with the CLR Profiler, which is discussed in an earlier blog post.&amp;nbsp; The Histogram view shows you a histogram of the allocations broken down by size, and you can quickly check to see if there's anything larger than 85000 bytes.&amp;nbsp; &lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;Aside from short-lived LOH allocations, the most common cause of memory related issues in ASP.NET apps is pinning managed memory during long async I/O operations.&amp;nbsp; ASP.NET itself does not do this, but perhaps&amp;nbsp;your application does?&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT face="Times New Roman" size=3&gt;Thanks,&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT face="Times New Roman" size=3&gt;Thomas&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8439140" width="1" height="1"&gt;</description></item><item><title>ASP.NET File Change Notifications, exactly which files and directories are monitored?</title><link>http://blogs.msdn.com/tmarq/archive/2007/11/02/asp-net-file-change-notifications-exactly-which-files-and-directories-are-monitored.aspx</link><pubDate>Fri, 02 Nov 2007 06:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5826773</guid><dc:creator>tmarq</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/5826773.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=5826773</wfw:commentRss><description>&lt;P&gt;Perhaps one of the most loved and hated features of ASP.NET is the ability to detect file changes and automatically recompile or reconfigure the application.&amp;nbsp; In development scenarios it’s very nice because you can access the application in a browser at the same time you’re modifying ASPX, ASAX, DLL, CONFIG, and other application files, and you don’t have to stop the web server process in order to update DLLs or configuration.&amp;nbsp; The changes are picked up immediately, but in order to make this possible we have to recycle the AppDomain.&amp;nbsp; In deployment scenarios, this feature can be a problem.&amp;nbsp; There are many files and folders (e.g. global.asax, web.config, BIN, App_Code, etc) that trigger an AppDomain unload when changed.&amp;nbsp; A subsequent request to the application will cause the AppDomain to be loaded again and the new files will be compiled, if necessary.&amp;nbsp; Restarting the application is expensive due to the disk access and recompilation of files.&amp;nbsp; Many applications also have expensive initialization steps that occur when the AppDomain is loaded, such as accessing SQL to populate local stores with frequently accessed data.&amp;nbsp; So what exactly does ASP.NET monitor and how?&lt;/P&gt;
&lt;P&gt;ASP.NET uses the Win32 function ReadDirectoryChangesW to monitor directories and files.&amp;nbsp; Given a directory handle, this function will let you know lots of information about changes to the directory or the files and directories contained within it.&amp;nbsp; By passing different flags, you tell it exactly what information you’re interested in and it informs you when there are changes.&amp;nbsp; ASP.NET monitors directories with the following flags (they are fairly self-explanatory, but you can refer to ReadDirectoryChangesW documentation for details):&lt;/P&gt;
&lt;P&gt;FILE_NOTIFY_CHANGE_FILE_NAME&lt;BR&gt;FILE_NOTIFY_CHANGE_DIR_NAME&lt;BR&gt;FILE_NOTIFY_CHANGE_CREATION&lt;BR&gt;FILE_NOTIFY_CHANGE_SIZE&lt;BR&gt;FILE_NOTIFY_CHANGE_LAST_WRITE&lt;BR&gt;FILE_NOTIFY_CHANGE_SECURITY&lt;/P&gt;
&lt;P&gt;The above flags are the ones that ASP.NET uses, but not all of them are used for each directory handle that is monitored.&amp;nbsp; So which directories are monitored?&amp;nbsp; By default in ASP.NET 2.0, there are six directory monitors for each application path, and two additional directory monitors for each virtual subdirectory path.&amp;nbsp; This is best explained with an example.&amp;nbsp; Suppose that we have an application with a virtual path of "/vpath" and a physical path of "c:\ppath".&amp;nbsp; If you make a request to a file located at "/vpath/f.aspx", the following directory monitors will be created:&amp;nbsp;&lt;/P&gt;
&lt;P&gt;#1) The application physical root path and all of its subdirectories are&amp;nbsp;monitored for subdirectory name changes&amp;nbsp;or deletions.&amp;nbsp; To be more precise, if FILE_NOTIFY_INFORMATION.Action is FILE_ACTION_RENAMED_OLD_NAME or FILE_ACTION_REMOVED, the AppDomain is unloaded.&amp;nbsp; This means that if you rename or delete a subdirectory beneath the application physical root, the application will be restarted.&amp;nbsp; This is discussed in &lt;A class="" title="Todd Carter's blog." href="http://blogs.msdn.com/toddca/archive/2005/12/01/499144.aspx" mce_href="http://blogs.msdn.com/toddca/archive/2005/12/01/499144.aspx"&gt;Todd Carter's blog post&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;ReadDirectoryChangesW is called with these arguments:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Directory= "c:\ppath"&lt;BR&gt;WatchSubtree=&amp;nbsp;True&lt;BR&gt;NotifyFilter=&amp;nbsp;FILE_NOTIFY_CHANGE_DIR_NAME&lt;/P&gt;
&lt;P&gt;The&amp;nbsp;stack trace for the call is:&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirMonCompletion..ctor(DirectoryMonitor dirMon, String dir, Boolean watchSubtree, UInt32 notifyFilter)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoring()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoringFile(String file, FileChangeEventHandler callback, String alias)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.FileChangesMonitor.StartMonitoringDirectoryRenamesAndBinDirectory(String dir, FileChangeEventHandler callback)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpRuntime.HostingInit(HostingEnvironmentFlags hostingFlags)&lt;BR&gt;&lt;BR&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;#2)&amp;nbsp; The "bin", "App_Code", "App_WebReferences", "App_GlobalResources", and "App_Browsers"&amp;nbsp;subdirectories of the application root folder are monitored&amp;nbsp;for creation, deletion, renaming,&amp;nbsp;ACL changes, changes to the last-write time, and changes to the size.&amp;nbsp; If any of these things change, the&amp;nbsp;AppDomain is unloaded.&amp;nbsp; Note that one directory monitor is created to monitor all five of these subfolders when they do not exist so that ASP.NET can catch their creation.&amp;nbsp; If they do exist, then a unique directory monitor is created for that subdirectory.&amp;nbsp; So if "bin" exists and the other four do not exist, you will have a total of two directory monitors, one for "bin" and one that monitors for the creation of the other four.&amp;nbsp; Or if "bin" and "App_Code" exist but the others do not, you will have three directory monitors, one for "bin", one for "App_Code", and one that monitors for the creation of the other three.&lt;/P&gt;
&lt;P&gt;ReadDirectoryChangesW is called with these arguments:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Directory= "c:\ppath"&lt;BR&gt;WatchSubtree=&amp;nbsp;False&lt;BR&gt;NotifyFilter=&amp;nbsp;FILE_NOTIFY_CHANGE_FILE_NAME &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | FILE_NOTIFY_CHANGE_DIR_NAME&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_CREATION&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_SIZE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_LAST_WRITE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;| FILE_NOTIFY_CHANGE_SECURITY&lt;/P&gt;
&lt;P&gt;The&amp;nbsp;stack trace for the call is:&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirMonCompletion..ctor(DirectoryMonitor dirMon, String dir, Boolean watchSubtree, UInt32 notifyFilter)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoring()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoringFile(String file, FileChangeEventHandler callback, String alias)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.FileChangesMonitor.ListenToSubdirectoryChanges(String dirRoot, String dirToListenTo)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.FileChangesMonitor.StartMonitoringDirectoryRenamesAndBinDirectory(String dir, FileChangeEventHandler callback)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpRuntime.HostingInit(HostingEnvironmentFlags hostingFlags)&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;#3) The machine.config and&amp;nbsp;root web.config file are monitored for changes.&amp;nbsp; A change to either of these files will unload the AppDomain.&lt;/P&gt;
&lt;P&gt;ReadDirectoryChangesW is called with these arguments:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Directory= "%WINDIR%\Microsoft.NET\Framework\v2.0.50727\Config"&lt;BR&gt;WatchSubtree=&amp;nbsp;FALSE&lt;BR&gt;NotifyFilter=&amp;nbsp;FILE_NOTIFY_CHANGE_FILE_NAME &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | FILE_NOTIFY_CHANGE_DIR_NAME&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_CREATION&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_SIZE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_LAST_WRITE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;| FILE_NOTIFY_CHANGE_SECURITY&lt;/P&gt;
&lt;P&gt;The&amp;nbsp;stack trace for the call is:&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirMonCompletion..ctor(DirectoryMonitor dirMon, String dir, Boolean watchSubtree, UInt32 notifyFilter)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoring()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoringFile(String file, FileChangeEventHandler callback, String alias)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.FileChangesMonitor.StartMonitoringFile(String alias, FileChangeEventHandler callback)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Configuration.WebConfigurationHost.StartMonitoringStreamForChanges(String streamName, StreamChangeCallback callback)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.MonitorStream(String configKey, String configSource, String streamname)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.InitConfigFromFile()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.Init(IInternalConfigRoot configRoot, BaseConfigurationRecord parent, String configPath, String locationSubPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.RuntimeConfigurationRecord.Create(InternalConfigRoot configRoot, IInternalConfigRecord parent, String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.Internal.InternalConfigRoot.GetConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.Internal.InternalConfigRoot.GetUniqueConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Configuration.HttpConfigurationSystem.GetUniqueConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.Init(CachedPathData parentData)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.GetConfigPathData(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.GetConfigPathData(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.GetConfigPathData(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.GetConfigPathData(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Configuration.RuntimeConfig.GetAppLKGConfig()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpRuntime.GetInitConfigSections&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpRuntime.HostingInit(HostingEnvironmentFlags hostingFlags)&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;#4)&amp;nbsp; The web.config of parent applications are monitored.&amp;nbsp; In this example, the root application "/" is the only parent.&amp;nbsp; A change to&amp;nbsp;this file will unload the AppDomain.&lt;/P&gt;
&lt;P&gt;ReadDirectoryChangesW is called with these arguments:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Directory= "c:\inetpub\wwwroot"&lt;BR&gt;WatchSubtree=&amp;nbsp;False&lt;BR&gt;NotifyFilter=&amp;nbsp;FILE_NOTIFY_CHANGE_FILE_NAME &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | FILE_NOTIFY_CHANGE_DIR_NAME&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_CREATION&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_SIZE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_LAST_WRITE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;| FILE_NOTIFY_CHANGE_SECURITY&lt;/P&gt;
&lt;P&gt;The&amp;nbsp;stack trace for the call is:&lt;BR&gt;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirMonCompletion..ctor(DirectoryMonitor dirMon, String dir, Boolean watchSubtree, UInt32 notifyFilter)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoring()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoringFile(String file, FileChangeEventHandler callback, String alias)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.FileChangesMonitor.StartMonitoringFile(String alias, FileChangeEventHandler callback)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Configuration.WebConfigurationHost.StartMonitoringStreamForChanges(String streamName, StreamChangeCallback callback)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.MonitorStream(String configKey, String configSource, String streamname)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.InitConfigFromFile()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.Init(IInternalConfigRoot configRoot, BaseConfigurationRecord parent, String configPath, String locationSubPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.RuntimeConfigurationRecord.Create(InternalConfigRoot configRoot, IInternalConfigRecord parent, String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.Internal.InternalConfigRoot.GetConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.Internal.InternalConfigRoot.GetUniqueConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Configuration.HttpConfigurationSystem.GetUniqueConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.Init(CachedPathData parentData)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.GetConfigPathData(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.GetConfigPathData(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Configuration.RuntimeConfig.GetAppLKGConfig()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpRuntime.GetInitConfigSections&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpRuntime.HostingInit(HostingEnvironmentFlags hostingFlags)&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;#5)&amp;nbsp;&amp;nbsp; The web.config&amp;nbsp;in the&amp;nbsp;application root is monitored.&amp;nbsp;&amp;nbsp;A change to&amp;nbsp;this file will unload the AppDomain.&lt;/P&gt;
&lt;P&gt;ReadDirectoryChangesW is called with these arguments:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Directory= "c:\ppath"&lt;BR&gt;WatchSubtree=&amp;nbsp;False&lt;BR&gt;NotifyFilter=&amp;nbsp;FILE_NOTIFY_CHANGE_FILE_NAME &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | FILE_NOTIFY_CHANGE_DIR_NAME&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_CREATION&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_SIZE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_LAST_WRITE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;| FILE_NOTIFY_CHANGE_SECURITY&lt;/P&gt;
&lt;P&gt;The&amp;nbsp;stack trace for the call is:&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirMonCompletion..ctor(DirectoryMonitor dirMon, String dir, Boolean watchSubtree, UInt32 notifyFilter)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoring()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoringFile(String file, FileChangeEventHandler callback, String alias)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.FileChangesMonitor.StartMonitoringFile(String alias, FileChangeEventHandler callback)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Configuration.WebConfigurationHost.StartMonitoringStreamForChanges(String streamName, StreamChangeCallback callback)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.MonitorStream(String configKey, String configSource, String streamname)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.InitConfigFromFile()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.Init(IInternalConfigRoot configRoot, BaseConfigurationRecord parent, String configPath, String locationSubPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.RuntimeConfigurationRecord.Create(InternalConfigRoot configRoot, IInternalConfigRecord parent, String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.Internal.InternalConfigRoot.GetConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.Internal.InternalConfigRoot.GetUniqueConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Configuration.HttpConfigurationSystem.GetUniqueConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.Init(CachedPathData parentData)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.GetConfigPathData(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Configuration.RuntimeConfig.GetAppLKGConfig()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpRuntime.GetInitConfigSections&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpRuntime.HostingInit(HostingEnvironmentFlags hostingFlags)&amp;nbsp;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;#6)&amp;nbsp; The hash.web file located in the "hash" subdirectory of the Temporary ASP.NET Files&amp;nbsp;folder is monitored.&amp;nbsp; This monitor was added to support development scenarios, in which both the ClientBuildManager and the runtime BuildManager are updating the application files.&amp;nbsp; Basically, since there are two build managers, there was a need to keep them in sync, and the hash.web file is used for that purpose.&lt;/P&gt;
&lt;P&gt;ReadDirectoryChangesW is called with these arguments:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Directory= "%WINDIR%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\repro\19a9eafa\c159e372\hash"&lt;BR&gt;WatchSubtree=&amp;nbsp;False&lt;BR&gt;NotifyFilter=&amp;nbsp;FILE_NOTIFY_CHANGE_FILE_NAME &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | FILE_NOTIFY_CHANGE_DIR_NAME&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_CREATION&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_SIZE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_LAST_WRITE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;| FILE_NOTIFY_CHANGE_SECURITY&lt;/P&gt;
&lt;P&gt;The&amp;nbsp;stack trace for the call is:&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirMonCompletion..ctor(DirectoryMonitor dirMon, String dir, Boolean watchSubtree, UInt32 notifyFilter)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoring()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoringFile(String file, FileChangeEventHandler callback, String alias)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.FileChangesMonitor.StartMonitoringFile(String alias, FileChangeEventHandler callback)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.CheckTopLevelFilesUpToDate2(StandardDiskBuildResultCache diskCache)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.CheckTopLevelFilesUpToDate(StandardDiskBuildResultCache diskCache)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.RegularAppRuntimeModeInitialize()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.Initialize()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.InitializeBuildManager()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpRuntime.HostingInit(HostingEnvironmentFlags hostingFlags)&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;As mentioned earlier, the six directory monitors mentioned above are created when a request is made to "/vpath/f.aspx".&amp;nbsp; If there is a subdirectory and a request is made to "/vpath/subdir/f.aspx", then two additional directory monitors will be created:&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;#7)&amp;nbsp;&amp;nbsp;The web.config&amp;nbsp;in any subdirectory of the application is monitored.&amp;nbsp;&amp;nbsp;A change to&amp;nbsp;this file will unload the AppDomain.&lt;/P&gt;
&lt;P&gt;ReadDirectoryChangesW is called with these arguments:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Directory= "c:\ppath\subdir"&lt;BR&gt;WatchSubtree=&amp;nbsp;False&lt;BR&gt;NotifyFilter=&amp;nbsp;FILE_NOTIFY_CHANGE_FILE_NAME &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | FILE_NOTIFY_CHANGE_DIR_NAME&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_CREATION&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_SIZE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_LAST_WRITE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;| FILE_NOTIFY_CHANGE_SECURITY&lt;/P&gt;
&lt;P&gt;The&amp;nbsp;stack trace for the call is:&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirMonCompletion..ctor(DirectoryMonitor dirMon, String dir, Boolean watchSubtree, UInt32 notifyFilter)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoring()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoringFile(String file, FileChangeEventHandler callback, String alias)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.FileChangesMonitor.StartMonitoringFile(String alias, FileChangeEventHandler callback)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Configuration.WebConfigurationHost.StartMonitoringStreamForChanges(String streamName, StreamChangeCallback callback)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.MonitorStream(String configKey, String configSource, String streamname)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.InitConfigFromFile()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.BaseConfigurationRecord.Init(IInternalConfigRoot configRoot, BaseConfigurationRecord parent, String configPath, String locationSubPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.RuntimeConfigurationRecord.Create(InternalConfigRoot configRoot, IInternalConfigRecord parent, String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.Internal.InternalConfigRoot.GetConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Configuration.Internal.InternalConfigRoot.GetUniqueConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Configuration.HttpConfigurationSystem.GetUniqueConfigRecord(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.Init(CachedPathData parentData)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.GetConfigPathData(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.GetConfigPathData(String configPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.CachedPathData.GetVirtualPathData(VirtualPath virtualPath, Boolean permitPathsOutsideApp)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpContext.GetFilePathData()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpContext.GetConfigurationPathData()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.ClientImpersonationContext.Start(HttpContext context, Boolean throwOnError)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpApplication.OnThreadEnter()&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;#8)&amp;nbsp; The "App_LocalResources" subdirectory of each virtual subdirectory&amp;nbsp;is monitored&amp;nbsp;for creation, deletion, renaming,&amp;nbsp;ACL changes, changes to the last-write time, and changes to the size.&amp;nbsp; If any of these things change, the&amp;nbsp;AppDomain is unloaded.&amp;nbsp; This monitor is created on the virtual directory itself if the "App_LocalResources" folder does not exist; otherwise, the monitor is created on the "App_LocalResources" directory.&lt;/P&gt;
&lt;P&gt;ReadDirectoryChangesW is called with these arguments:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Directory= "c:\ppath\subdir"&lt;BR&gt;WatchSubtree=&amp;nbsp;False&lt;BR&gt;NotifyFilter=&amp;nbsp;FILE_NOTIFY_CHANGE_FILE_NAME &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | FILE_NOTIFY_CHANGE_DIR_NAME&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_CREATION&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_SIZE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| FILE_NOTIFY_CHANGE_LAST_WRITE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;| FILE_NOTIFY_CHANGE_SECURITY&lt;/P&gt;
&lt;P&gt;The&amp;nbsp;stack trace for the call is:&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirMonCompletion..ctor(DirectoryMonitor dirMon, String dir, Boolean watchSubtree, UInt32 notifyFilter)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoring()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.DirectoryMonitor.StartMonitoringFile(String file, FileChangeEventHandler callback, String alias)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.FileChangesMonitor.ListenToSubdirectoryChanges(String dirRoot, String dirToListenTo)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.FileChangesMonitor.StartListeningToVirtualSubdirectory(VirtualPath virtualDir)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.EnsureFirstTimeDirectoryInit(VirtualPath virtualDir)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.GetBuildResultFromCacheInternal(String cacheKey, Boolean keyFromVPP, VirtualPath virtualPath, Int64 hashCode)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.GetVPathBuildResultFromCacheInternal(VirtualPath virtualPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean noAssert)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.UI.PageHandlerFactory.System.Web.IHttpHandlerFactory2.GetHandler&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpApplication.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp;amp; completedSynchronously)&amp;nbsp;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;So what about global.asax, or the f.aspx page that we used in the example?&amp;nbsp; Aren't they monitored?&amp;nbsp; Yes, they are, but they piggy back on one of the directory monitors listed above.&amp;nbsp; In the example, both global.asax and f.aspx would be added to the directory monitor described in #5.&amp;nbsp; Each directory monitor is capable of monitoring many different files, each with a unique callback for notification upon any changes.&amp;nbsp; I hope this helps your understanding.&amp;nbsp;I've also included an ASPX page code sample below that will display the number of requests, number of AppDomain restarts, and number of active directory monitors.&amp;nbsp; I'm not sure why you would want to know how many directory monitors are active in your application, but if someone asks you, you can always requests this page and&amp;nbsp;answer them.&amp;nbsp; :)&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class=code_sample style="BORDER-RIGHT: #ffffff 2px outset; BORDER-TOP: #ffffff 2px outset; BORDER-LEFT: #ffffff 2px outset; BORDER-BOTTOM: #ffffff 2px outset" class="code_sample"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=code_sample class="code_sample"&gt;&lt;XMP&gt;&lt;%@ import namespace="System.Diagnostics"%&gt;
&lt;%@ import namespace="System.Reflection"%&gt;

&lt;script runat="server" language="c#"&gt;
void Page_Load() {
    PerformanceCounter pc1 = new PerformanceCounter("ASP.NET Applications", 
                                                    "Requests Total", 
                                                    "__Total__");
    
    PerformanceCounter pc2 = new PerformanceCounter("ASP.NET", 
                                                    "Application Restarts");
    
    Type t = typeof(System.Web.HttpRuntime).Assembly.GetType("System.Web.DirMonCompletion");
    
    int dirMonCount = (int) t.InvokeMember("_activeDirMonCompletions",
                                           BindingFlags.NonPublic 
                                           | BindingFlags.Static
                                           | BindingFlags.GetField, 
                                           null, 
                                           null, 
                                           null); 
      
    // The perf client polls the server every 400 milliseconds
    System.Threading.Thread.Sleep(800);
    
    Response.Output.WriteLine("Requests={0},Restarts={1},DirMonCompletions={2}", 
                              pc1.NextValue(), 

                              pc2.NextValue(), 
                              dirMonCount);
}
&lt;/script&gt;
&lt;/XMP&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;-Thomas&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5826773" width="1" height="1"&gt;</description></item><item><title>Things you didn't know (and perhaps don't want to know) about ASP.NET Session State</title><link>http://blogs.msdn.com/tmarq/archive/2007/10/10/things-you-didn-t-know-and-probably-don-t-want-to-know-about-asp-net-session-state.aspx</link><pubDate>Wed, 10 Oct 2007 07:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5388893</guid><dc:creator>tmarq</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/5388893.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=5388893</wfw:commentRss><description>&lt;P&gt;I've uploaded a brief summary on the extensibility of ASP.NET Session State (see link to&amp;nbsp;AspNetSessionState.pdf below).&amp;nbsp; Many people aren't aware of how easy it is to implement&amp;nbsp;a custom&amp;nbsp;session state provider.&amp;nbsp; Having your very own disk based (file based) session state provider is just a few lines of code away.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5388893" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/tmarq/attachment/5388893.ashx" length="581653" type="application/pdf" /></item><item><title>Server.TransferRequest hangs or takes a long time to execute</title><link>http://blogs.msdn.com/tmarq/archive/2007/10/10/server-transferrequest-hangs-or-takes-a-long-time-to-execute.aspx</link><pubDate>Wed, 10 Oct 2007 06:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5388801</guid><dc:creator>tmarq</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/5388801.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=5388801</wfw:commentRss><description>&lt;P&gt;Server.TransferRequest is a new API in the IIS 7.0 release of ASP.NET.&amp;nbsp; It is essentially a server-side redirect.&amp;nbsp; When invoked, a new request context is created, called the child request, and it goes through the entire IIS 7.0/ASP.NET integrated pipeline.&amp;nbsp; The child request can be mapped to any of the handlers configured in IIS, and it's execution is no different than it would be if it was received via the HTTP stack.&amp;nbsp; The parent request jumps ahead in the pipeline to the end request notification, and waits for the child request to complete.&amp;nbsp; When the child request completes, the parent request executes the end request notifications and completes itself.&lt;/P&gt;
&lt;P&gt;Recently an issue was brought to my attention by &lt;A class="" title="Luis Abreu" href="http://msmvps.com/blogs/luisabreu/archive/2007/10/09/are-you-using-the-new-transferrequest.aspx" mce_href="http://msmvps.com/blogs/luisabreu/archive/2007/10/09/are-you-using-the-new-transferrequest.aspx"&gt;Luis Abreu&lt;/A&gt;.&amp;nbsp; Attempts to use Server.TransferRequest between the AcquireRequestState and ReleaseRequestState notifications will hang when session state is in use.&amp;nbsp; Luis does a great job of describing the problem, so let me just add that we will fix this as soon as possible.&lt;/P&gt;
&lt;P&gt;-Thomas&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5388801" width="1" height="1"&gt;</description></item><item><title>IIS 7.0, ASP.NET, pipelines, modules, handlers, and preconditions</title><link>http://blogs.msdn.com/tmarq/archive/2007/08/30/iis-7-0-asp-net-pipelines-modules-handlers-and-preconditions.aspx</link><pubDate>Thu, 30 Aug 2007 09:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4641157</guid><dc:creator>tmarq</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/4641157.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=4641157</wfw:commentRss><description>&lt;P&gt;&lt;B&gt;&lt;I&gt;1.0 What is the IIS Pipeline&lt;/I&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Conceptually, the IIS pipeline is a state machine with the following states:&lt;/P&gt;
&lt;P&gt;BEGIN_REQUEST&lt;BR&gt;AUTHENTICATE_REQUEST&lt;BR&gt;AUTHORIZE_REQUEST&lt;BR&gt;RESOLVE_REQUEST_CACHE&lt;BR&gt;MAP_REQUEST_HANDLER&lt;BR&gt;ACQUIRE_REQUEST_STATE&lt;BR&gt;PRE_EXECUTE_REQUEST_HANDLER&lt;BR&gt;&lt;B&gt;EXECUTE_REQUEST_HANDLER&lt;/B&gt;&lt;BR&gt;RELEASE_REQUEST_STATE&lt;BR&gt;UPDATE_REQUEST_CACHE&lt;BR&gt;LOG_REQUEST&lt;BR&gt;END_REQUEST&lt;/P&gt;
&lt;P&gt;When a request is received, it moves through the state machine step-by-step until completion.&amp;nbsp; Beginning with IIS 7.0, users can register their own code to be executed within any or all of the steps.&amp;nbsp; This code is referred to as a module.&amp;nbsp; In other words, users register modules to handle events in the pipeline.&amp;nbsp; (I will refer to the stages of the pipeline as steps, events, notifications, and sometimes combinations of one or more of these.&amp;nbsp; Don't let that confuse you.&amp;nbsp; They all mean the same thing.)&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;I&gt;2.0 Integrated vs. Classic Pipeline Modes&lt;/I&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;IIS 7.0 has two pipeline modes: integrated and classic.&amp;nbsp; The latter is sometimes referred to as ISAPI mode.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Integrated mode allows both managed and native modules to register for events in the IIS pipeline.&amp;nbsp; This enables many new scenarios, such as applying ASP.NET forms authentication to non-asp.net requests (static files, classic ASP files, etc).&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Classic mode is identical to IIS 6.0.&amp;nbsp; In classic mode, the ASP.NET pipeline (BeginRequest, AuthenticateRequest,…, EndRequest) runs entirely within the IIS pipeline’s &lt;B&gt;EXECUTE_REQUEST_HANDLER&lt;/B&gt; event.&amp;nbsp; Think of ASP.NET in classic mode as a pipeline within a pipeline.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;I&gt;3.0 Handlers vs. Modules&lt;/I&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Modules are units of code that have registered for one or more pipeline events. They perform authentication, authorization, logging, etc. There is one task that is reserved for a special module, known as a handler.&amp;nbsp; The handler’s unique job is to retrieve the resource that is requested in the URL.&amp;nbsp; All resources served by IIS are mapped to a handler in configuration.&amp;nbsp; If the configuration mapping does not exist, requests for the resource will receive a 404 HTTP status.&amp;nbsp; In addition to the configuration mapping, which takes place before the pipeline begins, the handler mapping can be changed during request execution in the MAP_REQUEST_HANDLER event.&amp;nbsp; This allows scenarios such as URL rewriting to work.&amp;nbsp; Handlers are notified, or executed, in the &lt;B&gt;EXECUTE_REQUEST_HANDLER&lt;/B&gt; step.&amp;nbsp; (Note that only the mapped handler is notified, as you would expect.)&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;I&gt;4.0 Handler and Module Configuration&lt;/I&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;IIS 7.0 introduces two new configuration sections: &amp;lt;handlers&amp;gt; and &amp;lt;modules&amp;gt;. The ASP.NET &amp;lt;httpHandlers&amp;gt; and &amp;lt;httpModules&amp;gt; sections still exist, but are only used when running in the classic pipeline mode.&amp;nbsp; The new IIS sections add a level of complexity which many users find confusing.&lt;/P&gt;
&lt;P&gt;First, if you're running in classic mode, your application should not require any changes.&amp;nbsp; The standard extensions served by ASP.NET ASPX, ASMX, AXD, etc are mapped to a handler in IIS configuration that invokes aspnet_isapi.dll and executes managed code just like it does on IIS 6.&amp;nbsp; If, however, you made changes to the IIS script mappings on IIS 6, you will need to make corresponding changes in IIS 7.&amp;nbsp; This will involve adding a &amp;lt;handler&amp;gt; mapping.&lt;/P&gt;
&lt;P&gt;On the other hand, if you're running in integrated mode, you will need to migrate your &amp;lt;httpHandler&amp;gt; and &amp;lt;httpModule&amp;gt; sections to the new &amp;lt;handler&amp;gt; and &amp;lt;module&amp;gt; sections.&amp;nbsp; For example, you can use the following command to migrate the &amp;lt;httpModules&amp;gt; section for the default web site:&lt;/P&gt;&lt;B&gt;%WINDIR%\system32\inetsrv\appcmd migrate config "Default Web Site/" -section:httpModules&lt;/B&gt; 
&lt;P&gt;The confusion occurs right about the time you start wondering how to add a managed module to the integrated pipeline that only executes for managed requests.&amp;nbsp; Or when you need to add a handler mapping that only applies to the integrated pipeline.&amp;nbsp; To perform these type actions, IIS uses preconditions on the module or handler to restrict the conditions under which it executes.&lt;/P&gt;
&lt;P&gt;For handlers, if you set &lt;B&gt;preCondition="integratedMode" &lt;/B&gt;in the &amp;lt;handler&amp;gt; mapping, the handler will only run in integrated mode.&amp;nbsp; On the other hand, if you set &lt;B&gt;preCondition="classicMode"&lt;/B&gt; the handler will only run in classic mode.&amp;nbsp; And if you omit both of these, the handler can run in both modes, although this is not possible for a managed handler.&lt;/P&gt;
&lt;P&gt;For modules, if you set &lt;B&gt;preCondition=”managedHandler”&lt;/B&gt; in the &amp;lt;module&amp;gt; entry, the module will only run for managed requests (a managed request is a request that has a managed handler).&amp;nbsp; If you omit this, the module will run for all requests.&amp;nbsp; Managed modules in the &amp;lt;modules&amp;gt; section are only called if you're running in the integrated pipeline.&amp;nbsp; If you're running in classic mode, then &amp;lt;httpModules&amp;gt; is used.&lt;/P&gt;
&lt;P&gt;Note that the “integratedMode” and “classicMode” preconditions only apply to handlers, and the “managedHandler” precondition only applies to modules. Also note that there are other preconditions that we have not discussed here.&amp;nbsp; These can be used to restrict the handler or module to a version of the framework, or specific processor architecture (32-bit or 64-bit), for example.&lt;/P&gt;
&lt;P&gt;The ASP.NET &amp;lt;httpHandlers&amp;gt; section has no knowledge of preconditions, and so you should never use them there.&amp;nbsp; The same is true for &amp;lt;httpModules&amp;gt;.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;I&gt;5.0 Troubleshooting&lt;/I&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;If you receive an error similar to the one below, your &amp;lt;handler&amp;gt; section is probably invalid.&amp;nbsp; &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;B&gt;HTTP Error 500.21 - Internal Server Error&lt;/B&gt;&lt;BR&gt;Handler "&amp;lt;HANDLER_NAME&amp;gt;" has a bad module "ManagedPipelineHandler" in its module list&lt;/BLOCKQUOTE&gt;
&lt;P&gt;You probably have a handler mapping that does not have the correct precondition.&amp;nbsp; IIS is not forgiving in regard to typos, and preconditions are case-sensitive.&amp;nbsp; The text must be &lt;B&gt;preCondition=”integratedMode”&lt;/B&gt; or &lt;B&gt;preCondition=”classicMode”&lt;/B&gt;.&lt;/P&gt;&lt;/SPAN&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4641157" width="1" height="1"&gt;</description></item><item><title>IIS7 kernel-mode authentication</title><link>http://blogs.msdn.com/tmarq/archive/2007/08/29/iis7-kernel-mode-authentication.aspx</link><pubDate>Wed, 29 Aug 2007 22:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4633085</guid><dc:creator>tmarq</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/4633085.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=4633085</wfw:commentRss><description>&lt;P&gt;This appears to be undocumented.&lt;/P&gt;
&lt;P&gt;By default, IIS7 uses kernel-mode authentication, which happens to have a large performance benefit.&amp;nbsp; There is a bug in kernel-mode authentication where requests that send credentials will fail unless an anonymous request has been made first.&amp;nbsp; Once an anonymous request has been made, requests that send credentials will succeed (if the authentication is successful).&amp;nbsp; This isn’t a problem for browsers that send an anonymous request first and only send credentials when challenged, but it is often a problem for clients like that send credentials on the initial request.&amp;nbsp; If you find that an HTTP client that you wrote fails on IIS7, you can confirm that this is the cause by disabling kernel-mode authentication with the following command:&lt;/P&gt;
&lt;P&gt;%windir%\system32\inetsrv\appcmd set config /section:windowsAuthentication /useKernelMode:false&lt;/P&gt;
&lt;P&gt;-Thomas&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4633085" width="1" height="1"&gt;</description></item><item><title>An Ounce of Prevention: Using System.Threading.Timer in an ASP.NET Application</title><link>http://blogs.msdn.com/tmarq/archive/2007/07/21/an-ounce-of-prevention-using-system-threading-timer-in-an-asp-net-application.aspx</link><pubDate>Sat, 21 Jul 2007 09:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3985550</guid><dc:creator>tmarq</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/3985550.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=3985550</wfw:commentRss><description>&lt;P&gt;Using a timer in an ASP.NET application is not as simple as it seems.&amp;nbsp; There are&amp;nbsp;three problems that commonly occur:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;ASP.NET applications shutdown for a number of reasons, and if the timer is not disposed before the AppDomain is unloaded, the timer may fire and crash the process with an unhandled AppDomainUnloadedException. 
&lt;LI&gt;The timer executes its callback on CLR Threadpool threads.&amp;nbsp; If the interval is small and the server is under a heavy load, the CLR Threadpool can queue up many work items.&amp;nbsp; This could result in multiple timer callbacks firing at or about the same time.&amp;nbsp; Or, if the timer callback itself takes a long time to execute, this could result in multiple concurrent callers.&amp;nbsp; Developers often incorrectly assume that only one thread will call the timer concurrently. 
&lt;LI&gt;If your timer callback invokes native code, via a P/Invoke or COM Interop call, and the AppDomain is unloaded while that code is being called, it may result in an unhandled AppDomainUnloadedException and crash the process. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;These problems are easily avoided.&amp;nbsp; There are a number of ways to be notified before the AppDomain is unloaded.&amp;nbsp; Within ASP.NET applications, you can listen to the &lt;A href="http://msdn2.microsoft.com/en-us/library/ms178473.aspx"&gt;Application_End&lt;/A&gt; event.&amp;nbsp; Another way would be to listen to the &lt;A class="" href="http://msdn2.microsoft.com/en-us/library/system.appdomain.domainunload.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.appdomain.domainunload.aspx"&gt;AppDomain.DomainUnload&lt;/A&gt; event.&amp;nbsp; Regardless of how you are notified, you’ll want to use code similar to the following to protect yourself against the aforementioned problems:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class=code_sample style="BORDER-RIGHT: #ffffff 2px outset; BORDER-TOP: #ffffff 2px outset; BORDER-LEFT: #ffffff 2px outset; BORDER-BOTTOM: #ffffff 2px outset" class="code_sample"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=code_sample class="code_sample"&gt;&lt;XMP&gt;// 1 if timer callback is executing; otherwise 0
int _inTimerCallback = 0;



Timer _timer = new Timer(new TimerCallback(this.TimerCallback), null, 1000, 1000);



//
// if the timer fires frequently or the callback runs for a long period, you may
// want to prevent two threads from calling it concurrently
//
void TimerCallback(object state) {
    // if the callback is already being executed, just return
    if (Interlocked.Exchange(ref _inTimerCallback, 1) != 0) {
        return;
    }
    try {
        // do work (potentially long running work that may call into native code)
    }
    finally {
        Interlocked.Exchange(ref _inTimerCallback, 0);
    }
}

//
// Before the AppDomain is shutdown, the timer must be disposed.  Otherwise,
// the underlying native timer may crash the process if it fires and attempts
// to call into the unloaded AppDomain.  In a multi-threaded environment,
// you may need to use synchronization to ensure the timer is disposed at most once.
//
internal void DisposeTimer() {
    Timer timer = _timer;
    if (timer != null
        &amp;&amp; Interlocked.CompareExchange(ref _timer, null, timer) == timer) {
            timer.Dispose();
        }
    }

    // if you don’t want the timer callback to be aborted during an AppDomain unload,
    // or if it calls into native code, then loop until the callback has completed
    while (_inTimerCallback != 0) {
        Sleep(100);
    }
}
&lt;/XMP&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3985550" width="1" height="1"&gt;</description></item><item><title>ASP.NET Thread Usage on IIS 7.0 and 6.0</title><link>http://blogs.msdn.com/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx</link><pubDate>Sat, 21 Jul 2007 04:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3984584</guid><dc:creator>tmarq</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/3984584.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=3984584</wfw:commentRss><description>&lt;P&gt;I'd like to briefly explain how ASP.NET uses threads when hosted on IIS 7.0 and IIS 6.0, as well as the configuration changes that you can make to alter the defaults. Please take a quick look at the “Threading Explained” section in &lt;A title="Chapter 6" href="http://msdn2.microsoft.com/en-us/library/ms998549.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms998549.aspx"&gt;Chapter 6&lt;/A&gt; of “Improving .NET Application Performance and Scalability”. Prior to v2.0 of the .NET Framework, it was necessary to tweak the processModel/maxWorkerThreads, processModel/maxIoThreads, httpRuntime/minFreeThreads, httpRuntime/minLocalRequestFreeThreads, and connectionManagement/maxconnection configuration. The v2.0 .NET Framework attempted to simplify this by adding a new &lt;A title=processModel/autoConfig href="http://msdn2.microsoft.com/en-us/library/7w2sway1(vs.80).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/7w2sway1(vs.80).aspx"&gt;processModel/autoConfig&lt;/A&gt; configuration, which made the changes for you at runtime. And with the introduction of IIS 7.0 and the ASP.NET integrated pipeline, we've introduced yet another element to the mix, a registry key named &lt;STRONG&gt;MaxConcurrentRequestsPerCPU&lt;/STRONG&gt;. Lets start with a discussion of how things worked on IIS 6.0 before discussing the changes made in IIS 7.0. &lt;/P&gt;
&lt;P&gt;When ASP.NET is hosted on IIS 6.0, the request is handed over to ASP.NET on an IIS I/O thread. ASP.NET immediately posts the request to the CLR ThreadPool and returns HSE_STATUS_PENDING to IIS. This frees up IIS threads, enabling IIS to serve other requests, such as static files. Posting the request to the CLR Threadpool also acts as a queue. The CLR Threadpool automatically adjusts the number of threads according to the workload, so that if the requests are high throughput there will only be 1 or 2 threads per CPU, and if the requests are high latency there will be potentially far more concurrently executing requests than 1 or 2 per CPU. The queuing provided by the CLR Threadpool is very useful, because while the requests are in the queue there is only a very small amount of memory allocated for the request, and it is all native memory. It’s not until a thread picks up the request and begins to execute that we enter managed code and allocate managed memory. &lt;/P&gt;
&lt;P&gt;The CLR Threadpool is not the only queue used by ASP.NET when hosted in IIS 6.0. There are also queues at the application level, within each AppDomain. If there is a lot of latency, the CLR Threadpool will grow and inject more active threads. At some point we would either run out of threads, not have enough threads left over for performing other tasks, or the memory associated with all the concurrently executing requests would be too much, so ASP.NET imposes a cap on the number of threads concurrently executing requests. This is controlled by the httpRuntime/minFreeThreads and httpRuntime/minLocalRequestFreeThreads settings. If the cap is exceeded, the request is queued in the application-level queue, and executed later when the concurrency falls back down below the limit. The performance of these application-level queues is really quite miserable. If you observe that the “ASP.NET Applications\Requests in Application Queue” performance counter is non-zero, you definitely have a performance problem. These queues were implemented to prevent thread exhaustion and contention related to web service requests. The problem was first described in &lt;A title="KB 821268" href="http://support.microsoft.com/kb/821268" mce_href="http://support.microsoft.com/kb/821268"&gt;KB 821268&lt;/A&gt;, which I had published many years ago. The KB article has been re-written a few times since it was originally published, and I hope nothing has been lost during the translations. &lt;/P&gt;
&lt;P&gt;For most usage scenarios, the changes recommended in the KB article are not necessary because v2.0 introduced &lt;A title=processModel/autoConfig href="http://msdn2.microsoft.com/en-us/library/7w2sway1(vs.80).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/7w2sway1(vs.80).aspx"&gt;processModel/autoConfig&lt;/A&gt;. However, the autoConfig setting may not work for everyone--it limits the number of concurrently executing requests per CPU to 12. An application with high latency may want to allow higher concurrency than this, in which case you can disable autoConfig and make the changes yourself. If you do allow higher concurrency, keep an eye on your working set. I believe the default works for about 90% of the applications out there. I do wish we had the foresight to name that setting maxConcurrentRequestsPerCPU, and allow it to be used to control concurrency, since that would be much easier to configure. I guess this is just another example of when business was just a little bit faster than the speed of thought. &lt;/P&gt;
&lt;P&gt;When ASP.NET is hosted on IIS 7.0 in integrated mode, the use of threads is a bit different. First of all, the application-level queues are no more. Their performance was always really bad, there was no hope in fixing this, and so we got rid of them. But perhaps the biggest difference is that in IIS 6.0, or ISAPI mode, ASP.NET restricts the number of &lt;STRONG&gt;threads&lt;/STRONG&gt; concurrently executing requests, but in IIS 7.0 integrated mode, ASP.NET restricts the number of concurrently executing &lt;STRONG&gt;requests&lt;/STRONG&gt;. The difference only matters when the requests are asynchronous (the request either has an asynchronous handler or a module in the pipeline completes asynchronously). Obviously if the reqeusts are synchronous, then the number of concurrently executing &lt;STRONG&gt;requests&lt;/STRONG&gt; is the same as the number of &lt;STRONG&gt;threads&lt;/STRONG&gt; concurrently executing requests, but if the requests are asynchronous then these two numbers can be quite different as you could have far more reqeusts than threads. So how do things work for IIS 7.0 integrated mode? Similar to IIS 6.0, the request is still handed over to ASP.NET on an IIS I/O thread. And ASP.NET immediately posts the request to the CLR Threadpool and returns pending. We found this thread switch was still necessary to maintain optimal performance for static file requests. So although you will take a performance hit if you’re only executing ASP.NET requests, if you have a mix of dynamic and static files, as we see with many large corporate workloads, this thread switch will actually free up threads for retrieving the static files. Finally, once the request is picked up by a thread from the CLR Threadpool, we check to see how many requests are currently executing. If the count is too high, the request is queued in a global (process-wide) queue. This global, native queue performs much better than the application-level queues used when we’re running in ISAPI mode (same as on IIS 6.0). There is very little memory associated with a queued request, and we have not entered managed code yet so there is no managed memory associated with it. And we respect the FIFO aspect of a queue, something we didn’t do with the application-level queues--if there was more than one application, there was no simple way to globally manage the individual queues. We did however have a difficult time trying to come up with a good configuration story for the IIS 7.0 changes. &lt;/P&gt;
&lt;P&gt;When I discuss how to configure thread usage for ASP.NET/IIS 7.0 integrated mode, please remember that we have a lot of pre-existing code and configuration, and you can’t just create something new the way you would like to without introducing backward compatibility issues. In this new mode, the CLR Threadpool is still controlled by the processModel configuration settings (autoConfig, maxWorkerThreads, maxIoThreads, minWorkerThreads, and minIoThreads). And autoConfig is still enabled, but its modifications to httpRuntime/minFreeThreads and httpRuntime/minLocalRequestFreeThreads do nothing, since the application-level queues do not exist. Perhaps we should have tried to use them to configure the global (process-wide) queue limits, but they have application scope (httpRuntime configuration is application specific), not process scope, not to mention being too difficult to understand. And because of some issues with using the configuration system that I won’t go into right now, we decided to use a registry key to control concurrency. So for IIS 7.0 integrated mode, a DWORD named &lt;STRONG&gt;MaxConcurrentRequestsPerCPU&lt;/STRONG&gt; within HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0 determines the number of concurrent &lt;STRONG&gt;requests&lt;/STRONG&gt; per CPU. By default, it does not exist and the number of requests per CPU is limited to 12. If you’re curious to see how much faster ASP.NET requests execute without the thread switch, you can set the value to 0. This will cause the request to execute on the IIS I/O thread, without switching to a CLR Threadpool thread. I don’t recommend this primarily because dynamic requests take a long time to execute relative to static requests, and I believe the overall performance of the system is better with the thread switch. However, and this is important, if your application consists of primarily or entirely asynchronous requests, it is likely that the default &lt;STRONG&gt;MaxConcurrentReqeustsPerCPU&lt;/STRONG&gt; limit of 12 may be too restrictive for you, especially if the requests are very long running. In this case, I do recommend either setting &lt;STRONG&gt;MaxConcurrentRequestsPerCPU&lt;/STRONG&gt; to 0 or increasing it to allow the concurrency that you would like. There's nothing wrong with setting MaxConcurrentRequestsPerCPU to a very high number, except that this will allow more requests to enter into managed code and execute concurrently, and this will consume more memory.&amp;nbsp; In fact, in v4.0, we have changed the default for MaxConcurrentRequestsPerCPU to 5000.&amp;nbsp; There's nothing special about 5000, other than it is a very large number, and will therefore allow plenty of async requests to execute concurrently.&amp;nbsp; The CLR ThreadPool will still do a great job maintaining the number of threads in the ThreadPool, so there should be no concern about this adversly impacting synchronous requests.&amp;nbsp; I know there are people out using ASP.NET 2.0 and developing &lt;A title=Comet href="http://en.wikipedia.org/wiki/Comet_(programming)" mce_href="http://en.wikipedia.org/wiki/Comet_(programming)"&gt;Comet&lt;/A&gt; or Comet-like applications on WS08 x64 servers, and they set MaxConcurrentRequestsPerCPU to 5000 and increase the HTTP.sys kernel queue limit.&lt;/P&gt;
&lt;P&gt;As a final remark, please note that the processModel/requestQueueLimit configuration limits the maximum number of requests in the ASP.NET system for both IIS 6.0 and IIS 7.0. This number is exposed by the "ASP.NET/Requests Current" performance counter, and when it exceeds the limit (default is 5000) we reject requests with a 503 status (Server Too Busy). &lt;/P&gt;
&lt;P&gt;-Thomas&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;UPDATE (Aug-18-2008)&lt;/STRONG&gt;: .NET Framework v3.5 SP1 released earlier this week and it includes an update to the v2.0 binaries that supports configuring IIS application pools via the aspnet.config file.&amp;nbsp; This configuration applies to integrated mode only (Classic/ISAPI mode ignores these settings).&amp;nbsp;The new aspnet.config config section with default values is:&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;system.web&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;applicationPool maxConcurrentRequestsPerCPU="12" maxConcurrentThreadsPerCPU="0" requestQueueLimit="5000"/&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/system.web&amp;gt;&lt;/P&gt;
&lt;P&gt;There is a corresponding IIS change in Windows7 which allows different aspnet.config files to be specified for each application pool (this change has not been ported to WS08). With this, you can configure each application pool differently.&amp;nbsp; The maxConcurrentRequestsPerCPU setting is the same as the registry key described above, except that the setting in aspnet.config will override the registry key value.&amp;nbsp; The maxConcurrentThreadsPerCPU setting is new, and allows concurrency to be gated by the number of threads, similar to the way it was done in Classic/ISAPI mode.&amp;nbsp; By default maxConcurrentThreadsPerCPU is disabled (has a value of 0), in favor of gating concurrency by the number of requests, primarily because&amp;nbsp;maxConcurrentRequestsPerCPU performs better (gating the number of threads is more complicated/costly to implement).&amp;nbsp; Normally you'll use request gating, but you now have the option of disabling it (set maxConccurrentRequestsPerCPU=0) and enabling maxConccurentThreadsPerCPU instead.&amp;nbsp; You can also enable both request and thread gating at the same time, and ASP.NET will ensure both requirements are met.&amp;nbsp; The requestQueueLimit setting is the same as processModel/requestQueueLimit, except that the setting in aspnet.config will override the machine.config setting.&amp;nbsp; All of this may be a little confusing, but for nearly everyone, my recommendation is that for ASP.NET 2.0 you should use the same settings as the defaults in ASP.NET v4.0; that is, set maxConcurrentRequestsPerCPU = "5000" and maxConcurrentThreadsPerCPU="0".&lt;/P&gt;
&lt;P&gt;-Thomas &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3984584" width="1" height="1"&gt;</description></item><item><title>Some history on the ASP.NET cache memory limits</title><link>http://blogs.msdn.com/tmarq/archive/2007/06/25/some-history-on-the-asp-net-cache-memory-limits.aspx</link><pubDate>Mon, 25 Jun 2007 20:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3523527</guid><dc:creator>tmarq</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/3523527.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=3523527</wfw:commentRss><description>&lt;P&gt;When v1.0 released, the only OS that ASP.NET supported was Win2k, the only process model was aspnet_wp, and the only architecture we supported was x86.&amp;nbsp; The aspnet_wp process model had a memory limit that was calculated at runtime during startup.&amp;nbsp; The limit was configurable (&amp;lt;processModel memoryLimit/&amp;gt;) as a percentage of physical RAM, and the default was 60%.&amp;nbsp; This limit prevents the process from consuming too much memory, especially in the face of a memory leak caused by user code, and allows the process to gracefully recycle.&amp;nbsp; We also had a feature known as the ASP.NET cache, which allows you to store objects with various expiration and validation policies.&amp;nbsp; The ASP.NET cache had built in logic that would drop entries when private bytes became too close to the private bytes memory limit for the process.&amp;nbsp; The actual percentage at which the cache began to drop entries is an implementation detail, and it is different on different hardware.&amp;nbsp; Suffice it to say that the cache dropped entries when memory usage approached the process memory limit.&lt;/P&gt;
&lt;P&gt;This default limit of 60% worked okay for machines with small amounts of RAM.&amp;nbsp; The 60% value was chosen to allow plenty of breathing room in the case where the limit was exceeded, since when that happens the new process is created before the old process has completely drained existing requests.&amp;nbsp;&amp;nbsp; Stress runs showed that memory limits higher than this resulted in too much memory paging during process recycles.&amp;nbsp; However, there was still a problem on boxes with large amounts of RAM.&amp;nbsp; For example, a box with 4GB of RAM had a default memory limit of 2.4GB (60%) by default.&amp;nbsp; This obviously doesn’t work given that the user mode address space is only 2GB.&amp;nbsp; Furthermore, ASP.NET apps typically had a very fragmented virtual address space.&amp;nbsp; We often saw apps throwing OutOfMemoryExceptions when virtual bytes reached about 1.5GB.&amp;nbsp; We found through experimentation that on x86 with a 2GB user-mode virtual address space, a conservative private bytes limit of 800 MB worked for most people.&amp;nbsp; We began recommending that people use this as a cap on private bytes.&amp;nbsp; Of course some applications could go beyond this, but if you wanted to play it safe, 800MB was a good limit for private bytes.&lt;/P&gt;
&lt;P&gt;In v1.1, we also supported WS03.&amp;nbsp; WS03 used a different process model (w3wp).&amp;nbsp; This process model gets its private bytes limit from IIS configuration ("Maximum Used Memory" on Recycling tab of Application Pool properties in IIS Manager), not the aforementioned &amp;lt;processModel memoryLimit/&amp;gt;.&amp;nbsp; Unfortunately, this limit had no default (it was not set by default).&amp;nbsp; So if the application used the ASP.NET cache, we would never drop entries and eventually you would start seeing OutOfMemoryExceptions.&amp;nbsp; These are non-recoverable, and required human intervention since the process would typically stay up and serve responses with a nicely formatted OutOfMemoryException error page from that point forward.&lt;/P&gt;
&lt;P&gt;In v2.0, we fixed this by exposing new configuration for the cache &amp;lt;caching&amp;gt;&amp;lt;cache privateBytesLimit/&amp;gt;&amp;lt;caching&amp;gt;.&amp;nbsp; Now the cache could have a memory limit independent of the process memory limit.&amp;nbsp; For backward compatibility, we also applied the process memory limit if it was set.&amp;nbsp;&amp;nbsp; Unfortunately, this complicated things a bit, and the way we calculate the cache memory limit is hidden to the user.&amp;nbsp; If you don’t set a cache or a process memory limit, we calculate one for you.&amp;nbsp;&amp;nbsp; If the user mode address space is 2GB, we use MIN(60% physical RAM, 800MB).&amp;nbsp; If the user mode address space is greater than 2GB and the process is 32-bit,&amp;nbsp;we use MIN(60% physical RAM, 1800MB).&amp;nbsp; And for 64-bit processes, we use MIN(60% physical RAM, 1TB).&amp;nbsp; That’s what happens if you don’t set any limits.&amp;nbsp; However, if you set both a cache memory limit and a process memory limit, we will use the minimum of the two.&amp;nbsp; And if you only set one, we will use the one you set.&amp;nbsp; Confused?&amp;nbsp; You'll be happy to know that the actual limit we use is exposed by the property &lt;A title=Cache.EffectivePrivateBytesLimit href="http://msdn.microsoft.com/en-us/library/system.web.caching.cache.effectiveprivatebyteslimit(VS.80).aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/system.web.caching.cache.effectiveprivatebyteslimit(VS.80).aspx"&gt;Cache.EffectivePrivateBytesLimit&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;While 60% may not work for boxes with 1TB of RAM, this value is configurable.&lt;/P&gt;
&lt;P&gt;Enough about private bytes.&amp;nbsp; The cache also has a physical memory limit that was introduced in v2.0.&amp;nbsp; It was introduced because the garbage collector (GC) becomes very aggressive in low memory conditions.&amp;nbsp; If the cache is consuming a bunch of memory and inducing the low memory condition, then it needs to release entries to alleviate the pressure on the GC.&amp;nbsp; In 2.0, the cache dropped entries when available memory was &amp;lt;= 11%.&amp;nbsp; We later discovered this was too aggressive, and have backed it off in 2.0 SP1 so that now we can use much more physical memory before dropping entries.&amp;nbsp; The actual limits that we use are an implementation detail, and they are different for different hardware.&lt;/P&gt;
&lt;P&gt;The v2.0 SP1 cache work was requested as a QFE by MS.com.&amp;nbsp; The KB article for this is at &lt;A href="http://support.microsoft.com/kb/938276" mce_href="http://support.microsoft.com/kb/938276"&gt;http://support.microsoft.com/kb/938276&lt;/A&gt;.&amp;nbsp; Anyone using the v2.0 ASP.NET cache should install this QFE.&amp;nbsp; It will of course be included in v2.0 SP1, when it is released.&lt;/P&gt;
&lt;P&gt;The cache memory manager should not be the primary eviction mechanism.&amp;nbsp; It is better to use expiration policies on the entries, so that they expire&amp;nbsp; before encountering memory pressure.&amp;nbsp; Most of the issues surrounding memory stem from the fact that the ASP.NET cache is not able to detect how much memory it is using.&amp;nbsp; It knows the number of entries, but not their sizes.&amp;nbsp; It uses Private Bytes for the process and available physical memory for the machine to determine when to drop entries, even though the cache may not be the cause of the memory pressure.&amp;nbsp; I suggest thinking of the cache memory manager as a safety net or fallback, and using expiration policies or other forms of validation to ensure that your cache entries are removed before encountering memory pressure.&amp;nbsp; If you only have a handful of cache entries this is not really an issue, and you can rely on the cache memory manager.&amp;nbsp; But if you're inserting unique entries on a per-request basis, or if you just simply have a very large number of entries, it makes sense to use expiration and/or validation policies.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3523527" width="1" height="1"&gt;</description></item><item><title>Orcas Beta 1 Visual Studio F5 Debugging on IIS 7 / Windows Vista</title><link>http://blogs.msdn.com/tmarq/archive/2007/06/13/orcas-beta-1-visual-studio-f5-debugging-on-iis-7-windows-vista.aspx</link><pubDate>Wed, 13 Jun 2007 18:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3270487</guid><dc:creator>tmarq</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/3270487.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=3270487</wfw:commentRss><description>&lt;P&gt;In Visual Studio Orcas Beta 1, the AJAX ScriptModule is listed in the web.config template used for version 3.5 web projects.&amp;nbsp; There is a known bug (DevDivBugs 78367) that prevents Visual Studio F5 debugging from working on IIS7 / Windows Vista&amp;nbsp;when a module in the IIS/ASP.NET integrated pipeline has an event handler for PreSendRequestHeaders or PreSendRequestContent.&amp;nbsp; Unfortunately, the ScriptModule listens to these.&lt;/P&gt;
&lt;P&gt;There are two workarounds:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;If you’re not using AJAX, you can remove the ScriptModule from the web.config file.&amp;nbsp; You need to remove it from the “&amp;lt;system.webServer&amp;gt;&amp;lt;modules&amp;gt;” configuration section, since this is the one used by the IIS/ASP.NET integrated pipeline.&amp;nbsp; Note that 2.0 web projects uses a web.config template that does not contain an entry for ScriptModule, and can therefore be debugged using F5 without making any changes.&lt;/LI&gt;
&lt;LI&gt;If you’re using AJAX, you can run the application in the “Classic .NET AppPool” instead of the “DefaultAppPool”.&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;If you need to use the IIS/ASP.NET integrated pipeline and AJAX, you’re best option is to manually attach to w3wp.exe instead of using F5 debugging.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This issue is fixed post Orcas Beta 1.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3270487" width="1" height="1"&gt;</description></item><item><title>The CLR Profiler</title><link>http://blogs.msdn.com/tmarq/archive/2007/06/09/the-clr-profiler.aspx</link><pubDate>Sat, 09 Jun 2007 04:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3173226</guid><dc:creator>tmarq</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/tmarq/comments/3173226.aspx</comments><wfw:commentRss>http://blogs.msdn.com/tmarq/commentrss.aspx?PostID=3173226</wfw:commentRss><description>&lt;H1 style="MARGIN: 12pt 0in 3pt; TEXT-ALIGN: center" align=center&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-bidi-font-family: 'Times New Roman'"&gt;The ClrProfiler&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;/H1&gt;
&lt;H2 style="MARGIN: 12pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;EM&gt;&amp;nbsp;&lt;/EM&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;H2 style="MARGIN: 12pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;EM&gt;1.0 Where can I get it?&lt;o:p&gt;&lt;/o:p&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyId=A362781C-3870-43BE-8926-862B40AA0CD0&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyId=A362781C-3870-43BE-8926-862B40AA0CD0&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyId=A362781C-3870-43BE-8926-862B40AA0CD0&amp;amp;displaylang=en&lt;/A&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 style="MARGIN: 12pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;EM&gt;2.0 Should I use it?&lt;o:p&gt;&lt;/o:p&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;When running performance tests, if the CPU is maximized and % Time in GC is greater than 5%, you can improve throughput by reducing allocations.&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Excessive garbage collection is often the culprit for low throughput.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The “.NET CLR Memory(w3wp)\% Time in GC” performance counter tells you how much time is spent doing collections.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The diagram below depicts how this is calculated:&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;| gc1_begin&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;| gc1_end&lt;SPAN style="mso-tab-count: 4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;| gc2_begin&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Time &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Wingdings; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;&lt;SPAN style="mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;à&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt; -------------------------------------------------------------------------------------&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;|&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;|&lt;SPAN style="mso-tab-count: 5"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;% Time in GC = 100 * (gc1_end – gc1_begin) / (gc2_begin – gc1_begin)&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;For ASP.NET applications, it is interesting to know what is allocated on a per request basis.&amp;nbsp; You can calculate &lt;U&gt;allocated bytes per request&lt;/U&gt; by&amp;nbsp;dividing ".NET CLR Memory(w3wp)\Allocated Bytes/Sec" by "ASP.NET Applications(__Total__)\Requests/sec".&amp;nbsp; &lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 style="MARGIN: 12pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;EM&gt;3.0 How do I create a profile?&lt;o:p&gt;&lt;/o:p&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL style="MARGIN-TOP: 0in" type=1&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Change the worker process identity to System.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Launch ClrProfiler.exe.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Uncheck “Profiling active”.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;From the File menu, select Profile ASP.NET.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Wait for a dialog to appear that says, “Waiting for ASP.NET to start common language runtime – this is the time to load your test page”.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Issue the first request to your page.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Check “Profiling active”.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Issue the second request to your page.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Uncheck “Profiling active”.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Click the “Kill ASP.NET” button&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo2; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;From the file menu, select “Save Profile as” if you would like to use the profile for comparisons later on.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 style="MARGIN: 12pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;EM&gt;4.0 How do I interpret the profile?&lt;o:p&gt;&lt;/o:p&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;There are many interesting ways to use the ClrProfiler.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I will discuss the two that I find most useful.&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;1.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The “Histogram Allocated Types” view displays a histogram by size.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In the left panel, you can select objects with the mouse, right click, and select “Show Who Allocated”.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;More importantly, in the right panel is listed the total number of objects allocated and their total size.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;If you right click in this region, you can select “Export Data to File” to save a CSV file that lists the min size, max size, # instances, and total size for each type.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;You can write a Perl script to quickly create a diff to assist you when comparing profiles.&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;2.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The “Allocation Graph” view is a graph depicting function calls and the total amount of memory and types of objects allocated by each call.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;At the far left you see the total amount of memory allocated by your test.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;As you move to the right, the function calls branch out and you see how much is allocated by each call.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;At the far right is a list of the objects that are allocated, and the total size of those allocations.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;You can right click anywhere in the graph and use various options, such as “Prune to Callers and Callees”, “Find Routine”, “Find interesting nodes”, etc. &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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 style="MARGIN: 12pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;EM&gt;5.0 Troubleshooting&lt;o:p&gt;&lt;/o:p&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;The ClrProfiler sets a custom environment block for both IISADMIN and W3SVC.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Normally this is removed when you click the “Kill ASP.NET” button, but if the profiler crashes you might have to remove it manually.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;To do this, delete the REG_SZ named Environment beneath HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IISADMIN and HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;A couple points worth noting:&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL style="MARGIN-TOP: 0in" type=disc&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;You only need to profile a single request.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;You can profile multiple requests, but the profile will grow quickly in size.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: l1 level1 lfo1; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;You do not want to include AppDomain load or AppDomain unload in the profile.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Uncheck “Profiling active” to avoid profiling during these times.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 style="MARGIN: 12pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;EM&gt;6.0 Documentation&lt;o:p&gt;&lt;/o:p&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&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; FONT-FAMILY: 'Verdana','sans-serif'"&gt;The author of the ClrProfiler wrote a document that I hear is quite good.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It is available with version 1.0 of the tool at &lt;A href="http://download.microsoft.com/download/4/4/2/442d67c7-a1c1-4884-9715-803a7b485b82/clr%20profiler.exe" mce_href="http://download.microsoft.com/download/4/4/2/442d67c7-a1c1-4884-9715-803a7b485b82/clr%20profiler.exe"&gt;http://download.microsoft.com/download/4/4/2/442d67c7-a1c1-4884-9715-803a7b485b82/clr%20profiler.exe&lt;/A&gt;.&lt;/P&gt;&lt;/SPAN&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3173226" width="1" height="1"&gt;</description></item></channel></rss>