<?xml-stylesheet type="text/xsl" href="/rss.xsl" media="screen"?><rss version="2.0"><channel><title>softlogger Latest Articles ::Design-Architecture</title><link>http://softlogger.com</link><description>softlogger Latest Articles ::Design-Architecture</description><ttl>180</ttl><item><title>Things in Metadata that are missing in Reflection</title><link>http://softlogger.com/20313/Design-Architecture/things-in-metadata-that-are-missing-in-reflection.aspx</link><description>&lt;p&gt;System.Reflection is a high-level way of &lt;a href="http://blogs.msdn.com/jmstall/archive/2007/03/15/describing-types-in-net.aspx"&gt;describing Types in .NET&lt;/a&gt; targetted at managed code consumers. The API is easy to use, but does not expose all the information that's actually present and affecting decisions.&lt;/p&gt; &lt;p&gt;For example, Reflection does not expose &lt;a href="http://blogs.msdn.com/jmstall/archive/2007/03/23/typedef-vs-typeref.aspx"&gt;TypeRef&lt;/a&gt;, MemberRef, AssemblyRef, or other Ref tokens.&amp;nbsp; These tokens are references to things in other assemblies. Reflection just resolves them for you (potentially invoking an event to get help from your app) and hands back the resolved object.&lt;/p&gt; &lt;p&gt;Similarly, reflection is also missing TypeSpecs. TypeSpecs are just binary signature blobs that describe compound types (arrays, generics, etc). Reflection will parse&amp;nbsp; the blob and resolve it to a real System.Type. &lt;/p&gt; &lt;p&gt;This entry is not a complete list of all things missing in reflection; nor am I going to get into the other problems in reflection here. For now, I'll just look at TypeRefs...&lt;/p&gt; &lt;p&gt;Imagine you have a class that inherits from a type in another assembly. At the metadata level, the base type is described with a TypeRef token. &lt;/p&gt; &lt;p&gt;1. Practically, that means you could use reflection to inspect what a base type &lt;em&gt;actually&lt;/em&gt; bound to,&amp;nbsp; but not what it was &lt;em&gt;supposed&lt;/em&gt; to bind to (as described in the original assemblyRef).&lt;/p&gt; &lt;p&gt;2. Another issue is that when you have a high-level API (Reflection) that loses information over a low level API (IMetadataImport), you risk that the high-level API won't be able to talk to the low level API because it may not be able to provide it with the information the low level API requests. &lt;/p&gt; &lt;p&gt;3. In related trivia, ILDasm can print TypeRef, TypeSpec tokens:&lt;/p&gt; &lt;p&gt;//000010:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Hi!" + arg);&lt;br&gt;&amp;nbsp; IL_0001:&amp;nbsp; ldstr&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Hi!" /* 70000001 */&lt;br&gt;&amp;nbsp; IL_0006:&amp;nbsp; ldarg.0&lt;br&gt;&amp;nbsp; IL_0007:&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string [mscorlib/*23000001*/]System.String/*&lt;strong&gt;01000012&lt;/strong&gt;*/::Concat(string,&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string) /* 0A000010 */&lt;br&gt;&amp;nbsp; IL_000c:&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void [mscorlib/*23000001*/]System.Console/*&lt;strong&gt;01000013&lt;/strong&gt;*/::WriteLine(string) /* 0A000011 */&lt;br&gt;&amp;nbsp; IL_0011:&amp;nbsp; nop &lt;p&gt;So the inability to get the raw unresolved tokens from Reflection would prevent you from writing ILDasm on reflection that could print the above snippet.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8218761" width="1" height="1"&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=20313"&gt;</description><author>Mike Stalls blog                                                                                    </author><pubDate>2008-03-15T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>High memory usage with usercontrols in IE (using Debug Diag)</title><link>http://softlogger.com/19427/Design-Architecture/high-memory-usage-with-usercontrols-in-ie-using-debug-diag.aspx</link><description>&lt;p&gt;I was helping a colleague with an interesting case yesterday concerning a memory leak in IE when using winforms usercontrols. &lt;/p&gt; &lt;p&gt;We got a nice little repro with a&amp;nbsp;very basic&amp;nbsp;user control that displayed&amp;nbsp;a picture and each time the page was refreshed it appeared to leak quite a bit of memory,&lt;br&gt;and inducing a garbage collection had no effect on the memory.&lt;/p&gt; &lt;p&gt;I started off with setting it up on my machine, and then I used &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&amp;amp;displaylang=en"&gt;Debug Diag 1.1&lt;/a&gt; &amp;nbsp;to track down the leak... Debug diag is not all that great for managed/.net memory leaks since the GC manages the memory for you as I'll show later... but I figured that since I had a repro it was worth a try... &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Some notes on how debug diag works:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Debug diag is basically a debugging helper that allows you to take memory dumps of a process or set up different rules like crash rules, memory rules, exception rules and hang rules.&amp;nbsp; It also has a leaktracking feature which I will talk about in more detail in a bit.&amp;nbsp; It also has a number of scripts (and allows you to write your own scripts) for automated analysis.&amp;nbsp; Basically you load up a dump file in debug diag (can even be a dump file gathered with windbg) and choose the script you want (hang, crash or memory) and then Debug Diag will produce a report with stacks and information about what it thinks is the problem.&lt;/p&gt; &lt;p&gt;The &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&amp;amp;displaylang=en"&gt;downloads page&lt;/a&gt; has very nice information concerning how you use Debug Diag to troubleshoot different issues.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Debug diag and memory leaks:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This excerpt is copied straight from the downloads page:&lt;/p&gt; &lt;p&gt;&lt;em&gt;To debug memory and handle usage, use one of the following:&lt;br&gt;1. Create a leak rule against the process in question. The leak monitoring feature will track memory allocations inside the process. Tracking is implemented by injecting a DLL (leaktrack.dll) into the specified process and monitoring memory allocations over time. When configuring a memory and handle leak rule, you can specify memory dump generation based on time or memory usage. &lt;br&gt;2. Using the “processes” view, right-click the process in question and select the “monitor for leaks” option. When the process has grown to the suspected problem size, manually dump the process by right-clicking on the same process in the processes view and choosing the “Create Full Userdump” option.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;In esscence what this means is that any memory that has been allocated and not been de-allocated will be reported as a possible leak.&amp;nbsp; It is very important that you turn on leaktracking for a sufficient amount of time (or raise in memory usage) that you can weed out the real leaks for the stacks that allocated memory recently and just hasn't had the time to de-allocate it. &lt;/p&gt; &lt;p&gt;Another item worth mentioning is that by default debug diag will not track any stacks for the first 15 minutes (to avoid mixing in all the allocations made on startup which are not really leaks but just getting you up to baseline memory usage).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Debugging&amp;nbsp;the issue:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I started up by&amp;nbsp;browsing to the html page that instantiated the user control so that i had&amp;nbsp;everything loaded and then&amp;nbsp;I started up debug diag and then&amp;nbsp;I followed these steps to get a memory dump.&amp;nbsp; &lt;/p&gt; &lt;p&gt;1. Since my repro was very quick (way less than 15 minutes) I&amp;nbsp;went in&amp;nbsp;to "tools/options and settings"&amp;nbsp;in debug diag and checked&amp;nbsp;the box "Record call stacks immediately when monitoring for leaks..." under the preferences tab. &lt;/p&gt; &lt;p&gt;2. In the process tab I found my iexplore.exe process, right clicked it and choose "Monitor for leaks"&lt;/p&gt; &lt;p&gt;3. I refreshed the page like crazy to get a&amp;nbsp;a leak of around 200 MB in the IE process&lt;/p&gt; &lt;p&gt;4. Then I right clicked the iexplore.exe process under the process tab again and choose "Create Full Userdump"&lt;/p&gt; &lt;p&gt;Since leaktrack.dll stores all the info about the allocated memory in memory there is a slight overhead that leaktrack itself creates.&amp;nbsp; It is usually not all that significant but I wanted to mention it in case you ever look at a memory analysis and wonder what all the memory on the leaktrack heap is doing. &lt;/p&gt; &lt;p&gt;My next step was to go in to debug diag under the advanced analysis tab and choose "Add data files" to get my dump analysed, and then&amp;nbsp;I chose "Memory Preassure Analyzers" from the analysis scripts and hit "Start Analysis".&amp;nbsp; After that it is time for a coffee break:)&amp;nbsp; &lt;/p&gt; &lt;p&gt;Back from coffee, debug diag has finished running the analysis and popped up IE with an mhtml file with the results and on top it showed the following...&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/tess/WindowsLiveWriter/HighmemoryusagewithusercontrolsinIEusing_CBEF/image%7B0%7D%5B7%5D.png" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="226" src="http://blogs.msdn.com/blogfiles/tess/WindowsLiveWriter/HighmemoryusagewithusercontrolsinIEusing_CBEF/image%7B0%7D_thumb%5B3%5D.png" width="1131" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&amp;nbsp;And a little bit further down&amp;nbsp;on the page under leaktracking summary it had this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/tess/WindowsLiveWriter/HighmemoryusagewithusercontrolsinIEusing_CBEF/image%7B0%7D%5B10%5D.png" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="149" src="http://blogs.msdn.com/blogfiles/tess/WindowsLiveWriter/HighmemoryusagewithusercontrolsinIEusing_CBEF/image%7B0%7D_thumb%5B4%5D.png" width="347" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;So from this we can see that we have been tracking for 45 seconds (way shorter than I would normally recommend but this was a quick leak).&amp;nbsp; We have allocated 213 MB and the biggest memory user seems to be GdiPlus.dll (192,56 MB)&lt;/p&gt; &lt;p&gt;Note that mscorwks.dll has used up 20,73 MB.&amp;nbsp; If you have a .net memory leak or high .net memory usage you won't really see the individual allocators here.&amp;nbsp; All .net leaks will show up as a high amount of outstanding allocations from mscorwks.dll which is why I mentioned earlier that tracking .net leaks with debug diag doesn't work all that well.&lt;/p&gt; &lt;p&gt;If I click on GdiPlus.dll I will get to a section in the html file with more details about the GdiPlus allocations, including stacks which is extremely useful since it tells you where/why all this memory is allocated...&lt;/p&gt;&lt;pre class="debug"&gt;&lt;strong&gt;Call stack sample 1&lt;/strong&gt;

Address   0x0bc00000 
Allocation Time   00:00:11 since tracking started 
Allocation Size   5,49 MBytes 




Function   Source   Destination 
&lt;strong&gt;GdiPlus!GpMemoryBitmap::AllocBitmapData+71   &lt;br&gt;&lt;/strong&gt;GdiPlus!GpMemoryBitmap::AllocBitmapMemory+26   
GdiPlus!GpMemoryBitmap::BeginSink+14b    
GdiPlus!GpJpegDecoder::CallBeginSink+6c       
GdiPlus!get_sos+285       
GdiPlus!GpJpegDecoder::Decode+b7       
ntdll!NtQueryVirtualMemory+12       
kernel32!VirtualQueryEx+1d    
mscorwks!RuntimeMethodHandle::SerializationInvoke+36       
System.RuntimeMethodHandle.SerializationInvoke(System.Object, System.SignatureStruct, System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)       
System.Reflection.RuntimeConstructorInfo.SerializationInvoke(System.Object, System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)       
System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(System.Object, System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)&lt;br&gt;System.Runtime.Serialization.ObjectManager.FixupSpecialObject(System.Runtime.Serialization.ObjectHolder)
System.Runtime.Serialization.ObjectManager.DoFixups()
System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(...)       
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(...)&lt;br&gt;System.Resources.ResourceReader.DeserializeObject(Int32)&lt;br&gt;System.Resources.ResourceReader.LoadObjectV2(Int32, System.Resources.ResourceTypeCode ByRef)
System.Resources.ResourceReader.LoadObject(Int32, System.Resources.ResourceTypeCode ByRef)
System.Resources.RuntimeResourceSet.GetObject(System.String, Boolean, Boolean)
System.Resources.RuntimeResourceSet.GetObject(System.String, Boolean)
System.Resources.ResourceManager.GetObject(System.String, System.Globalization.CultureInfo, Boolean)
System.Resources.ResourceManager.GetObject(System.String, System.Globalization.CultureInfo)
&lt;strong&gt;LeakControl.Properties.Resources.get_SomePicture()       
LeakControl.LeakControlTest.InitializeComponent()
&lt;/strong&gt;mscorwks!CallDescrWorker+33 &lt;br&gt;...&lt;/pre&gt;
&lt;p&gt;This call stack sample tells us that 11 seconds in to&amp;nbsp;the tracking this stack allocated 5,49 MB in the GdiPlus!GpMemoryBitmap::AllocBitmapData which is extremely interesting in this case since this method was the one that allocated the 192,26 MB according to the&amp;nbsp;summary.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Looking a bit further down the stack we can see that this is&amp;nbsp;done because we load up&amp;nbsp;some picture resource in the InitializeComponent method for the control. Basically this means that this is something that happens every time the control is loaded.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Turns out that the picture it is loading up is pretty large&amp;nbsp;so that is why we see the 5 MB here&amp;nbsp;(my guess though is that&amp;nbsp;this is done on purpose to show the leak faster).&amp;nbsp; Anyways, this begs the question, why is this bitmap not released?&amp;nbsp; If the control goes out of scope&amp;nbsp;GdiPlus should release this memory as part of the destruction of the control. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Debugging with&amp;nbsp;windbg:&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The next step for me was to load up the dump in windbg to figure out what was up with these controls.&lt;/p&gt;
&lt;p&gt;Running !dumpheap -stat&amp;nbsp;I found&amp;nbsp;that there were 36 controls in memory (same amount as the times&amp;nbsp;I had refreshed)&lt;/p&gt;&lt;pre class="debug"&gt;7912d7c0         66         5,884 System.Int32[]
07b9719c         36         6,768 System.Windows.Forms.PictureBox
7911bbd0        289         8,092 System.Security.SecurityElement
&lt;strong&gt;07b54664         36         8,208 LeakControl.LeakControlTest
&lt;/strong&gt;07b5dc08         82         8,604 System.Windows.Forms.PropertyStore+ObjectEntry[]
79120830        226         9,944 System.Reflection.Emit.OpCode
79104368        491        11,784 System.Collections.ArrayList
79109778        289        16,184 System.Reflection.RuntimeMethodInfo
7912d9bc        101        23,448 System.Collections.Hashtable+bucket[]
7912d8f8        862        79,784 System.Object[]
790fd8c4      6,150       357,664 System.String
7912dae8        100    20,847,312 System.Byte[]
Total 13,093 objects, Total size: 21,516,680&lt;/pre&gt;
&lt;p&gt;So something&amp;nbsp;is obviously keeping these controls alive...&lt;/p&gt;
&lt;p&gt;I dumpped them all out using !dumpheap -mt 07b54664&lt;/p&gt;&lt;pre class="debug"&gt;0:000&amp;gt; !dumpheap -mt 07b54664         
Using our cache to search the heap.
   Address         MT     Size  Gen
...
05300d84 07b54664      228    2 LeakControl.LeakControlTest 
05301910 07b54664      228    2 LeakControl.LeakControlTest 
0530237c 07b54664      228    2 LeakControl.LeakControlTest 
&lt;strong&gt;05302de8 07b54664      228    2 LeakControl.LeakControlTest 
&lt;/strong&gt;05303854 07b54664      228    2 LeakControl.LeakControlTest 
053042c0 07b54664      228    2 LeakControl.LeakControlTest 
...
Statistics:
      MT    Count    TotalSize Class Name
07b54664       36        8,208 LeakControl.LeakControlTest
Total 36 objects, Total size: 8,208
&lt;/pre&gt;
&lt;p&gt;And then I picked one at random and ran !gcroot on it to see where it was rooted (i.e. what was holding it alive), and among other things I saw this... &lt;/p&gt;&lt;pre class="debug"&gt;0:000&amp;gt; !gcroot 05302de8 
...
DOMAIN(04731890):HANDLE(Strong):78416d0:Root:  053031f8(System.Runtime.Remoting.ServerIdentity)-&amp;gt;
  053031e8(System.Runtime.Remoting.ObjectHandle)-&amp;gt;
  05302de8(LeakControl.LeakControlTest)&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;So it is rooted in a System.Runtime.Remoting.ObjectHandle in a ServerIdentity&amp;nbsp;object, whatever that means;)&lt;/p&gt;
&lt;p&gt;Then&amp;nbsp;I&amp;nbsp;searched for "System.Runtime.Remoting.ObjectHandle usercontrol" and found this... &lt;a href="http://support.microsoft.com/kb/555916"&gt;KB 555916 Memory leak in .NET Managed Usercontrols&lt;/a&gt; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;I just have to stop here and say WOW!!!&amp;nbsp; I really didn't have a clue that these types of kb article.&amp;nbsp; And when I say this type I mean 1. Community Solutions Content and 2. Really nice debugging summaries...&amp;nbsp; Kudos to Alvin Bruney who wrote the article, love it:)&lt;/p&gt;
&lt;p&gt;So anyways, it turns out that the reason these objects (and thus the bitmaps) stick around is because remoting is used to communicate between the IE domain and the domain associated with the security zone of the user control.&amp;nbsp; The remoting lease is set in this case to 5 minutes by default which means that these objects will stick around until the lease is up to avoid having to recreate them for further communication between the domains.&lt;/p&gt;
&lt;p&gt;You can lower the lease time but as Alvin mentions in the article that may affect the performance.&amp;nbsp;&amp;nbsp; Typically though it should not be an issue since these types of controls are generally not that memory consuming, but if it is, and needs to be, then lowering the lease time is probably the best option.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Btw, I will try to get the memory lab review done today or tomorrow so we can get on with the next lab which will be a high CPU perf issue.&lt;/p&gt;
&lt;p&gt;Laters&lt;/p&gt;
&lt;p&gt;Tess&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7793289" width="1" height="1"&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=19427"&gt;</description><author>If broken it is, fix it you should</author><pubDate>2008-02-19T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>Dealing with Exceptions in a Future</title><link>http://softlogger.com/19063/Design-Architecture/dealing-with-exceptions-in-a-future.aspx</link><description>&lt;p&gt;Besides waiting, the another important issue when dealing with Futures is how to deal with exceptions thrown by the user specified code.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Option 1: Ignore the Exception&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Don't take any actions in the future code and force users to write exception free code.&amp;#160; IMHO this is not the best way to approach the problem.&amp;#160; The code will be running in the thread pool and unhandled exceptions in the thread pool result in the taking down of an appdomain/process.&amp;#160; In addition Futures are designed to be simple.&amp;#160; Adding a try/catch around every lambda is not practical and/or readable.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Option 2: Catch and Swallow&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Catch the exception on the background thread and swallow it.&amp;#160; Silently failing is in many cases worse than actually crashing.&amp;#160; Behavior will become flaky and the user/developer won't have any indication there is an error.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Option 3: Re-throw the Exception when Wait is called&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Catch and save the exception when it occurs on the background thread.&amp;#160; Then when Wait() is called on a Future re-throw the exception.&amp;#160; This makes exception handled deterministic.&lt;/p&gt;  &lt;p&gt;It's also very similar to the exception handling semantics of calling a method.&amp;#160; The only difference is that users must handle the exception at the point of method completion vs invocation.&amp;#160; For synchronous methods this is just the same point.&lt;/p&gt;  &lt;p&gt;The big downside to this approach is the stack trace information is lost from the exception.&amp;#160; Re-throwing will instead add the stack trace at the point of the re-throw.&amp;#160; Not having stack trace information makes it very difficult to actually track down the source of an error.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Option 4: Re-throw a new Exception when Wait is called &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is very similar to Option #3.&amp;#160; The only difference is when the user calls Wait, throw a new exception and make the original exception an inner exception of the new one.&amp;#160; We'll call this exception FutureException.&amp;#160; This has the advantages of option 3 and in addition will preserve the stack trace information from the original exception.&lt;/p&gt;  &lt;p&gt;There is a downside to this approach though.&amp;#160; Users can no longer have different catch blocks to handle the different types of exceptions that can be thrown.&amp;#160; &lt;/p&gt;  &lt;pre class="code"&gt;            &lt;span style="color: rgb(0,0,255)"&gt;try
&lt;/span&gt;            {
                &lt;span style="color: rgb(43,145,175)"&gt;Future&lt;/span&gt;.Create(() =&amp;gt; SomeOperation());
            }
            &lt;span style="color: rgb(0,0,255)"&gt;catch&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;IOException&lt;/span&gt; ex)
            {
                &lt;span style="color: rgb(0,128,0)"&gt;// ...
&lt;/span&gt;            }
            &lt;span style="color: rgb(0,0,255)"&gt;catch&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;InvalidOperationException&lt;/span&gt; ex)
            {
                &lt;span style="color: rgb(0,128,0)"&gt;// ...
&lt;/span&gt;            }&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Instead the user can only catch a Future exception and examine the inner result to take corrective action.&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;            &lt;span style="color: rgb(0,0,255)"&gt;try
&lt;/span&gt;            {
                &lt;span style="color: rgb(43,145,175)"&gt;Future&lt;/span&gt;.Create(() =&amp;gt; SomeOperation());
            }
            &lt;span style="color: rgb(0,0,255)"&gt;catch&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;FutureException&lt;/span&gt; ex)
            {
                &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; type = ex.InnerException.GetType();
                &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (type == &lt;span style="color: rgb(0,0,255)"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;IOException&lt;/span&gt;))
                {
                    &lt;span style="color: rgb(0,128,0)"&gt;// ...
&lt;/span&gt;                }
                &lt;span style="color: rgb(0,0,255)"&gt;else&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (type == &lt;span style="color: rgb(0,0,255)"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;InvalidOperationException&lt;/span&gt;))
                {
                    &lt;span style="color: rgb(0,128,0)"&gt;// ...
&lt;/span&gt;                }
            }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This doesn't actually limit any functionality but users may find the syntax uncomfortable.&amp;#160; VB users can still do exception filtering but this is not at option for C# users.&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Try
&lt;/span&gt;            Future.Create(&lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt;() SomeOperation())
        &lt;span style="color: rgb(0,0,255)"&gt;Catch&lt;/span&gt; ex &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; Exception &lt;span style="color: rgb(0,0,255)"&gt;When&lt;/span&gt; ex.InnerException.GetType() &lt;span style="color: rgb(0,0,255)"&gt;Is&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;GetType&lt;/span&gt;(IOException)

        &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Try&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;The FutureException class is straight forward.&amp;#160; A simple implementation of the exception snippet will do the trick. &lt;/p&gt;

&lt;pre class="code"&gt;    [&lt;span style="color: rgb(0,0,255)"&gt;global&lt;/span&gt;::System.&lt;span style="color: rgb(43,145,175)"&gt;Serializable&lt;/span&gt;]
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;FutureException&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;Exception
&lt;/span&gt;    {


        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; FutureException() { }
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; FutureException(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; message) : &lt;span style="color: rgb(0,0,255)"&gt;base&lt;/span&gt;(message) { }
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; FutureException(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; message, &lt;span style="color: rgb(43,145,175)"&gt;Exception&lt;/span&gt; inner) : &lt;span style="color: rgb(0,0,255)"&gt;base&lt;/span&gt;(message, inner) { }
        &lt;span style="color: rgb(0,0,255)"&gt;protected&lt;/span&gt; FutureException(
          System.Runtime.Serialization.&lt;span style="color: rgb(43,145,175)"&gt;SerializationInfo&lt;/span&gt; info,
          System.Runtime.Serialization.&lt;span style="color: rgb(43,145,175)"&gt;StreamingContext&lt;/span&gt; context)
            : &lt;span style="color: rgb(0,0,255)"&gt;base&lt;/span&gt;(info, context) { }
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7614564" width="1" height="1"&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=19063"&gt;</description><author>jaredpars WebLog</author><pubDate>2008-02-11T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>ASP.NET Hang and OutOfMemory exceptions caused by STA components</title><link>http://softlogger.com/18544/Design-Architecture/asp-net-hang-and-outofmemory-exceptions-caused-by-sta-components.aspx</link><description>&lt;P&gt;I have talked about &lt;A href="http://blogs.msdn.com/tess/archive/2006/03/27/561715.aspx" mce_href="http://blogs.msdn.com/tess/archive/2006/03/27/561715.aspx"&gt;blocked finalizers&lt;/A&gt; before and this issue is a special case of blocked finalizers where we are not really finalizing a .NET object but rather cleaning up all Com Callable Wrappers (CCWs) and getting stuck doing that.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Problem description:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The situation we are facing is that the ASP.NET process starts to go hey wire both in response times and in memory usage.&amp;nbsp; All of a sudden memory just starts growing and growing and we need to figure out why.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Troubleshooting:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;We took a memory dump when memory usage was high (~837 MB private bytes which we could see from the dump size) with adplus -hang -pn w3wp.exe, but really the dump could have just been taken anytime after the memory started rapidly increasing.&lt;/P&gt;
&lt;P&gt;Around ~469 MB of the memory are pure .net objects (as we can see from GC Heap Size in !eeheap -gc) and the large object segments are minimal so there isn't a whole lot of large objects... &lt;/P&gt;&lt;PRE class=debug&gt;0:015&amp;gt; !eeheap -gc
Number of GC Heaps: 2
------------------------------
Heap 0 (000db128)
generation 0 starts at 0x33bc0c98
generation 1 starts at 0x338bc070
generation 2 starts at 0x02410038
ephemeral segment allocation context: none
 segment    begin allocated     size            reserved
00176d48 7b451688  7b467f9c 0x00016914(92,436) 00003000
000e96e0 7a721784  7a74248c 0x00020d08(134,408) 00003000
000e1ee0 790d6358  790f5800 0x0001f4a8(128,168) 00003000
02410000 02410038  0640f130 0x03fff0f8(67,105,016) 01fdf000
17d80000 17d80038  1bd69da8 0x03fe9d70(67,018,096) 0000e000
2a070000 2a070038  2e063b38 0x03ff3b00(67,058,432) 00009000
321d0000 321d0038  33caad50 0x01adad18(28,159,256) 01cb6000
Large object heap starts at 0x0a410038
 segment    begin allocated     size            reserved
&lt;STRONG&gt;&lt;EM&gt;0a410000 0a410038  0a4234f0 0x000134b8(79,032) 01fdf000
&lt;/EM&gt;&lt;/STRONG&gt;Heap Size  0xdb215fc(229,774,844)
------------------------------
Heap 1 (000dc138)
generation 0 starts at 0x38146e28
generation 1 starts at 0x37e5033c
generation 2 starts at 0x06410038
ephemeral segment allocation context: none
 segment    begin allocated     size            reserved
06410000 06410038  0a40ee00 0x03ffedc8(67,104,200) 01fdf000
1bd80000 1bd80038  1fce8e6c 0x03f68e34(66,489,908) 00077000
26070000 26070038  2a05b85c 0x03feb824(67,024,932) 03ff7000
36510000 36510038  38a8cc68 0x0257cc30(39,308,336) 01a7c000
Large object heap starts at 0x0c410038
 segment    begin allocated     size            reserved
&lt;STRONG&gt;&lt;EM&gt;0c410000 0c410038  0c410048 0x00000010(16) 01fff000
&lt;/EM&gt;&lt;/STRONG&gt;Heap Size  0xe4d0060(239,927,392)
------------------------------
&lt;STRONG&gt;GC Heap Size  0x1bff165c(469,702,236)&lt;/STRONG&gt;
&lt;/PRE&gt;
&lt;P&gt;If we dump out&amp;nbsp;the managed heaps with &lt;A href="http://blogs.msdn.com/tess/archive/2005/11/25/496973.aspx" mce_href="http://blogs.msdn.com/tess/archive/2005/11/25/496973.aspx"&gt;!dumpheap -stat&lt;/A&gt; the&amp;nbsp;most memory consuming objects are shown below...&lt;/P&gt;
&lt;P&gt;I have grouped them like this:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#800000&gt;Red - UI related items &lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt;Green - Data related items&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#000000&gt;Black - Regular items like string, char[] etc.&amp;nbsp; (note, these are very likely linked to the data related or ui related items as well)&lt;/FONT&gt;&lt;/P&gt;&lt;PRE class=debug&gt;...
&lt;FONT color=#008000&gt;0ec99d1c     38,575       617,200 Oracle.DataAccess.Client.OracleParameterCollection
&lt;/FONT&gt;&lt;FONT color=#ff0000&gt;&lt;FONT color=#800000&gt;68a35670     11,135       623,560 System.Web.UI.WebControls.HiddenField
0ec693f4        848       630,912 ASP.aspx_mypage_aspx&lt;/FONT&gt;
&lt;/FONT&gt;7a742f30     37,751       755,020 System.ComponentModel.EventHandlerList+ListEntry
&lt;FONT color=#800000&gt;68a652e8     73,493       881,916 System.Web.UI.WebControls.BorderStyle
&lt;/FONT&gt;7a753288     55,789       892,624 System.Collections.Specialized.NameObjectCollectionBase+NameObjectEntry
&lt;FONT color=#008000&gt;653c5b14     15,019       961,216 System.Data.DataRow
0ec96d64     34,834       975,352 Oracle.DataAccess.Client.MetaData
&lt;/FONT&gt;79124670      3,936       985,932 System.Char[]
&lt;FONT color=#800000&gt;68a2c690     14,989     1,019,252 System.Web.UI.HtmlControls.HtmlTableRow
&lt;/FONT&gt;&lt;FONT color=#008000&gt;653c3e94      7,703     1,140,044 System.Data.DataColumn
653d61c0      1,137     1,177,932 System.Data.RBTree`1+Node[[System.Data.DataRow, System.Data]][]
0ec9bd4c     36,872     1,179,904 Oracle.DataAccess.Client.OracleRowUpdatingEventHandler
&lt;/FONT&gt;&lt;FONT color=#800000&gt;10fa17dc     13,293     1,329,300 MyControls.MyCheckBox
&lt;/FONT&gt;791052bc    117,882     1,414,584 System.Int16
&lt;FONT color=#800000&gt;68a37884     17,827     1,426,160 System.Web.UI.WebControls.Label
&lt;/FONT&gt;79104f64    151,695     1,820,340 System.Boolean
&lt;FONT color=#800000&gt;68a3e7a0    155,042     1,860,504 System.Web.UI.WebControls.FontInfo
0ec634fc     25,512     2,040,960 MyControls.MyTextBox
68a7d910     26,604     2,128,320 System.Web.UI.WebControls.Button
68a2f704    105,846     2,540,304 System.Web.UI.CssStyleCollection
&lt;/FONT&gt;&lt;FONT color=#008000&gt;0ec96c84     98,136     2,747,808 Oracle.DataAccess.Client.ColMetaRef
&lt;/FONT&gt;&lt;FONT color=#800000&gt;68a2f694    202,158     3,234,528 System.Web.UI.AttributeCollection
&lt;/FONT&gt;79103b6c     75,803     3,335,332 System.Threading.ReaderWriterLock
&lt;FONT color=#800000&gt;68a2f7fc     94,486     3,401,496 System.Web.UI.ControlCollection
&lt;/FONT&gt;&lt;FONT color=#008000&gt;0ec9ae14     36,872     3,687,200 Oracle.DataAccess.Client.OracleDataAdapter
&lt;/FONT&gt;&lt;FONT color=#800000&gt;68a6423c    150,531     4,816,992 System.Web.UI.WebControls.FontUnit
68a2c918     85,276     5,457,664 System.Web.UI.HtmlControls.HtmlTableCell
0ec6322c     69,949     5,595,920 MyControls.MyLabel
&lt;/FONT&gt;&lt;FONT color=#008000&gt;0ec9b404     36,872     5,604,544 Oracle.DataAccess.Client.OracleCommandBuilder
&lt;/FONT&gt;&lt;FONT color=#800000&gt;68a31bdc    476,216     5,714,592 System.Web.UI.IndexedString
68a884a0     96,876     5,812,560 System.Web.UI.LiteralControl
68a7ca28    365,718     5,851,488 System.Web.UI.Pair
7ae75d7c    252,629     6,063,096 System.Drawing.Color
68a85ea0    392,440     6,279,040 System.Web.UI.StateBag
&lt;/FONT&gt;&lt;FONT color=#008000&gt;0ec9975c     40,043     6,406,880 Oracle.DataAccess.Client.OracleCommand
&lt;/FONT&gt;&lt;FONT color=#800000&gt;68a7745c    159,338     7,010,872 System.Web.UI.WebControls.Style
&lt;/FONT&gt;790fea70    139,382     7,805,392 System.Collections.Hashtable
&lt;FONT color=#800000&gt;68a92e2c    177,707     7,819,108 System.Web.UI.Control+OccasionalFields
68a86004    331,329     7,951,896 System.Web.UI.WebControls.Unit
&lt;/FONT&gt;790fed1c    698,227     8,378,724 System.Int32
791036b0    401,277     9,630,648 System.Collections.ArrayList
000daa58        296    10,030,596      Free
7a747bac    378,430    10,596,040 System.Collections.Specialized.ListDictionary
7a747ad4    608,586    12,171,720 System.Collections.Specialized.HybridDictionary
7a747c78    837,066    16,741,320 System.Collections.Specialized.ListDictionary+DictionaryNode
79124418      4,555    17,726,104 System.Byte[]
&lt;FONT color=#008000&gt;0ec9a664    165,910    17,918,280 Oracle.DataAccess.Client.OracleParameter
&lt;/FONT&gt;&lt;FONT color=#800000&gt;68a131b4  1,758,380    28,134,080 System.Web.UI.StateItem
&lt;/FONT&gt;79124228    705,459    31,266,188 System.Object[]
791242ec    142,053    43,835,496 System.Collections.Hashtable+bucket[]
790fa3e0  1,032,738   116,787,020 System.String
Total 11,377,657 objects, Total size: 469,685,264
&lt;/PRE&gt;
&lt;P&gt;So here, most of the memory is going to either datarelated items, ui related items or generic&amp;nbsp;objects.&amp;nbsp; &amp;nbsp;In short, let's say we got rid of all the ASP.aspx_mypage_aspx objects for example, then it is very likely that we would get rid of most of the UI related items.&amp;nbsp; And if we got rid of all the DataSets in the dump we would probably get rid of all or most of the datarelated items... &lt;/P&gt;
&lt;P&gt;If I focus on the aspx pages and dump them out... and then !gcroot a few of those aspx pages to see where they are rooted we get this... &lt;/P&gt;&lt;PRE class=debug&gt;0:000&amp;gt; !dumpheap -mt 0ec693f4        
Using our cache to search the heap.
   Address         MT     Size  Gen
&lt;STRONG&gt;0251f0ec &lt;/STRONG&gt;0ec693f4      744    2 ASP.aspx_mypage_aspx 
02555c90 0ec693f4      744    2 ASP.aspx_mypage_aspx 
0259cfc0 0ec693f4      744    2 ASP.aspx_mypage_aspx 
025d3ca0 0ec693f4      744    2 ASP.aspx_mypage_aspx 
0260a85c 0ec693f4      744    2 ASP.aspx_mypage_aspx 
02641294 0ec693f4      744    2 ASP.aspx_mypage_aspx 
02677f44 0ec693f4      744    2 ASP.aspx_mypage_aspx 
026aeaf4 0ec693f4      744    2 ASP.aspx_mypage_aspx 
0270622c 0ec693f4      744    2 ASP.aspx_mypage_aspx
... 


0:015&amp;gt; !gcroot &lt;STRONG&gt;0251f0ec &lt;/STRONG&gt;
Note: Roots found on stacks may be false positives. Run "!help gcroot" for
more info.
Scan Thread 15 OSTHread a28
Scan Thread 19 OSTHread 43c
Scan Thread 20 OSTHread b94
Scan Thread 21 OSTHread 15c
Scan Thread 13 OSTHread ce8
Scan Thread 22 OSTHread 750
Scan Thread 5 OSTHread d3c
Scan Thread 24 OSTHread 234
Scan Thread 7 OSTHread dc0
Scan Thread 25 OSTHread c28
Scan Thread 26 OSTHread 528
Scan Thread 8 OSTHread aec
Scan Thread 6 OSTHread 754
Scan Thread 27 OSTHread bc8
Scan Thread 28 OSTHread fb4
Scan Thread 29 OSTHread 20c
Scan Thread 31 OSTHread 88c
&lt;STRONG&gt;Finalizer queue:Root:  0251f0ec(ASP.aspx_mypage_aspx)
&lt;/STRONG&gt;Finalizer queue:Root:  02523b0c(MyControls.MyTextBox)-&amp;gt;
  02523aa8(MyControls.MyWebTextBox)-&amp;gt;
  0251f0ec(ASP.aspx_mypage_aspx)
Finalizer queue:Root:  025243e0(MyControls.MyClientEvents)-&amp;gt;
  02523aa8(MyControls.MyWebTextBox)-&amp;gt;
  0251f0ec(ASP.aspx_mypage_aspx)
Finalizer queue:Root:  02524d88(MyControls.MyTextBox)-&amp;gt;
  02524d24(MyControls.MyWebTextBox)-&amp;gt;
  0251f0ec(ASP.aspx_mypage_aspx)
Finalizer queue:Root:  0252565c(MyControls.MyClientEvents)-&amp;gt;
  02524d24(MyControls.MyWebTextBox)-&amp;gt;
  0251f0ec(ASP.aspx_mypage_aspx)
&lt;/PRE&gt;
&lt;P&gt;The page is rooted in the finalizer queue, both by itself and as a member variable to a MyWebTextBox object (probably the _parent&amp;nbsp;member variable).&lt;/P&gt;
&lt;P&gt;This means two things&lt;/P&gt;
&lt;P&gt;1. The finalizer is probably blocked, otherwise items&amp;nbsp;usually won't be rooted in the Finalizer queue long enough for us to catch it in a dump&lt;BR&gt;2. The ASP.aspx_mypage_aspx, the&amp;nbsp;MyTextBox and&amp;nbsp;the MyClientEvents&amp;nbsp;classes all have finalizers or derrive from classes that have finalizers which seems very odd and is probably unneccesary.&amp;nbsp; &lt;A href="http://msdn2.microsoft.com/en-us/library/b1yfkh5e(vs.71).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/b1yfkh5e(vs.71).aspx"&gt;This article&lt;/A&gt; is a good resource for understanding how the finalizer/dispose pattern should be implemented, and &lt;A href="http://blogs.msdn.com/tess/archive/2006/03/27/561715.aspx" mce_href="http://blogs.msdn.com/tess/archive/2006/03/27/561715.aspx"&gt;this article&lt;/A&gt; explains why unneccesary finalizers are bad (under the topic "What can make us spend a lot of our time in GC?")&lt;/P&gt;
&lt;P&gt;If the finalizer is blocked no objects can be finalized which will lead to rapid memory growth, so a blocked finalizer will most definitely explain our problem.&amp;nbsp; The reason these objects (UI and Data objects) don't go away then is of course because they would have to be finalized to be garbage collected.&lt;/P&gt;
&lt;P&gt;So, let's have a look at the finalizer thread&lt;/P&gt;&lt;PRE class=debug&gt;0:015&amp;gt; !threads
ThreadCount: 27
UnstartedThread: 0
BackgroundThread: 17
PendingThread: 0
DeadThread: 10
Hosted Runtime: no
                                      PreEmptive   GC Alloc           Lock
       ID OSID ThreadOBJ    State     GC       Context       Domain   Count APT Exception
  15    1  a28 000d75f0   1808220 Enabled  3823b58c:3823bb08 000d3fe8     0 &lt;STRONG&gt;STA&lt;/STRONG&gt; (Threadpool Worker)
&lt;STRONG&gt;  19    2  43c 000dd5f0      b220 Enabled  00000000:00000000 000d3fe8     0 MTA (Finalizer)
&lt;/STRONG&gt;  20    3  b94 000f20b0    80a220 Enabled  00000000:00000000 000d3fe8     0 MTA (Threadpool Completion Port)
  21    4  15c 000f5318      1220 Enabled  00000000:00000000 000d3fe8     0 Ukn
  13    5  ce8 0014c3f0   880a220 Enabled  00000000:00000000 000d3fe8     0 MTA (Threadpool Completion Port)
  22    6  750 00122f70   880b220 Enabled  00000000:00000000 000d3fe8     0 MTA (Threadpool Completion Port)
   5    7  d3c 00160890       220 Enabled  00000000:00000000 000d3fe8     0 Ukn
  24    8  234 0f8a90d8   180b220 Enabled  3816cea0:3816ee28 000d3fe8     0 MTA (Threadpool Worker)
   7    a  dc0 0f8ae008       220 Enabled  00000000:00000000 000d3fe8     0 Ukn
XXXX    b    0 0015d0c8   1801820 Enabled  00000000:00000000 000d3fe8     0 Ukn (Threadpool Worker)
XXXX    c    0 115a0f68   1801820 Enabled  00000000:00000000 000d3fe8     0 Ukn (Threadpool Worker)
XXXX    d    0 11dadf88   1801820 Enabled  00000000:00000000 000d3fe8     0 Ukn (Threadpool Worker)
XXXX    e    0 13168018   1801820 Enabled  00000000:00000000 000d3fe8     0 Ukn (Threadpool Worker)
  25    f  c28 1441b018   180b220 Enabled  3823bde4:3823db08 000d3fe8     0 MTA (Threadpool Worker)
XXXX   10    0 1352b3b8   1801820 Enabled  00000000:00000000 000d3fe8     0 Ukn (Threadpool Worker)
  26   11  528 1433d008       220 Enabled  00000000:00000000 000d3fe8     0 Ukn
   8   12  aec 14416bc0       220 Enabled  00000000:00000000 000d3fe8     0 Ukn
   6   13  754 1444b828       220 Enabled  00000000:00000000 000d3fe8     0 Ukn
  27   14  bc8 14526248       220 Enabled  00000000:00000000 000d3fe8     0 Ukn
  28   15  fb4 145cb220       220 Enabled  00000000:00000000 000d3fe8     0 Ukn
XXXX   16    0 1461a008   1801820 Enabled  00000000:00000000 000d3fe8     0 Ukn (Threadpool Worker)
  29   17  20c 147abac8       220 Enabled  00000000:00000000 000d3fe8     0 Ukn
XXXX   18    0 164a02e8   1801820 Enabled  00000000:00000000 000d3fe8     0 Ukn (Threadpool Worker)
XXXX   19    0 230be290   1801820 Enabled  00000000:00000000 000d3fe8     0 Ukn (Threadpool Worker)
XXXX    9    0 0f8a99a8   1801820 Enabled  00000000:00000000 000d3fe8     0 Ukn (Threadpool Worker)
XXXX   1a    0 227c2f18   1801820 Enabled  00000000:00000000 000d3fe8     0 Ukn (Threadpool Worker)
  31   1b  88c 227d1c98       220 Enabled  00000000:00000000 000d3fe8     0 Ukn

0:015&amp;gt; &lt;STRONG&gt;~19s&lt;/STRONG&gt;
eax=01eff518 ebx=00099cd0 ecx=01eff518 edx=7743345e esi=00000740 edi=00000000
eip=7c97ed54 esp=01eff254 ebp=01eff2c4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCallRet:
7c97ed54 c3              ret

0:019&amp;gt; kb 2000
ChildEBP RetAddr  
01eff250 7c972124 ntdll!KiFastSystemCallRet
01eff254 7c82baa8 ntdll!NtWaitForSingleObject+0xc
01eff2c4 7c82ba12 kernel32!WaitForSingleObjectEx+0xac
01eff2d8 774854ef kernel32!WaitForSingleObject+0x12
&lt;STRONG&gt;01eff2f4 77549905 ole32!GetToSTA+0x6f
&lt;/STRONG&gt;01eff314 77547ed7 ole32!CRpcChannelBuffer::SwitchAptAndDispatchCall+0xcb
01eff3f4 77455349 ole32!CRpcChannelBuffer::SendReceive2+0xc1
01eff460 77484eee ole32!CAptRpcChnl::SendReceive+0xab
01eff4b4 77c8127e ole32!CCtxComChnl::SendReceive+0x91
01eff4d0 77c813ca rpcrt4!NdrProxySendReceive+0x43
01eff8b8 77c811bd rpcrt4!NdrClientCall2+0x206
01eff8d8 77bf3a12 rpcrt4!ObjectStublessClient+0x8b
01eff8e8 77484c23 rpcrt4!ObjectStubless+0xf
01eff970 774d28f3 ole32!CObjectContext::InternalContextCallback+0x126
01eff9c0 79f2340f ole32!CObjectContext::ContextCallback+0x85
01effa0c 79f23362 mscorwks!CtxEntry::EnterContextOle32BugAware+0x2b
01effb2c 79f231ef mscorwks!CtxEntry::EnterContext+0x2db
01effb60 7a0426dc mscorwks!RCWCleanupList::ReleaseRCWListInCorrectCtx+0xc4
&lt;STRONG&gt;01effbb0 79f23058 mscorwks!RCWCleanupList::CleanupAllWrappers+0x77
&lt;/STRONG&gt;01effbf4 79f75f2d mscorwks!SyncBlockCache::CleanupSyncBlocks+0xec
01effdb8 79f34ff2 mscorwks!Thread::DoExtraWorkForFinalizer+0x40
01effdc8 79ecb4a4 mscorwks!SVR::GCHeap::FinalizerThreadWorker+0xc6
01effdd8 79ecb442 mscorwks!ManagedThreadBase_DispatchInner+0x4d
01effe6c 79ecb364 mscorwks!ManagedThreadBase_DispatchMiddle+0xb0
01effea8 79ed5e8b mscorwks!ManagedThreadBase_DispatchOuter+0x6d
01effed0 79ed5e56 mscorwks!ManagedThreadBase_NoADTransition+0x32
01effedc 79f6fd87 mscorwks!ManagedThreadBase::FinalizerBase+0xb
01efff14 79ecb00b mscorwks!SVR::GCHeap::FinalizerThreadStart+0xbb
01efffb8 7c826063 mscorwks!Thread::intermediateThreadProc+0x49
01efffec 00000000 kernel32!BaseThreadStart+0x34
&lt;/PRE&gt;
&lt;P&gt;The finalizer thread (which we found from the !threads output) is definitely doing something and based on what we know about objects beeing rooted in the Finalizer queue it has&amp;nbsp;probably been stuck here for a while. &amp;nbsp;&lt;/P&gt;
&lt;P&gt;The finalizer is not neccesarily finalizing a managed object, instead it is cleaning up all com wrappers, and to release them it has to&amp;nbsp;get on an STA thread. &lt;/P&gt;
&lt;P&gt;If we look at the !threads output&amp;nbsp;again,&amp;nbsp;specifically at the APT (Appartment) column we can see that our only STA thread is thread 15 so that is likely where it is trying to go. &amp;nbsp;&lt;/P&gt;&lt;PRE class=debug&gt;0:019&amp;gt; ~15s
eax=2d220b44 ebx=000d75f0 ecx=2d220ca4 edx=000b4883 esi=0000022c edi=00000000
eip=7c97ed54 esp=01b1fc70 ebp=01b1fce0 iopl=0         nv up ei ng nz ac pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000297
ntdll!KiFastSystemCallRet:
7c97ed54 c3              ret

0:015&amp;gt; kbL 2000
ChildEBP RetAddr  Args to Child              
01b1fc6c 7c972124 7c82baa8 0000022c 00000000 ntdll!KiFastSystemCallRet
01b1fc70 7c82baa8 0000022c 00000000 01b1fcb4 ntdll!NtWaitForSingleObject+0xc
01b1fce0 79e77fd1 0000022c 00009c40 00000000 kernel32!WaitForSingleObjectEx+0xac
01b1fd24 79e77f9a 0000022c 00009c40 00000000 mscorwks!CLREventWaitHelper+0x2f
01b1fd74 79e77f50 00009c40 00000000 00000000 mscorwks!CLREvent::WaitEx+0x117
01b1fd84 79f5b69c 00009c40 00000000 00000000 mscorwks!CLREvent::Wait+0x17
01b1fe04 7a112052 000bf560 00009c40 00000000 mscorwks!ThreadpoolMgr::SafeWait+0x73
01b1fe2c 7a112206 eeb88f9d 00000000 7a1120b5 mscorwks!ThreadpoolMgr::EnterRetirement+0x8e
01b1fe94 79f71123 00000000 00000000 00000000 mscorwks!ThreadpoolMgr::WorkerThreadStart+0x360
01b1ffb8 7c826063 000bcbf0 00000000 00000000 mscorwks!ThreadpoolMgr::intermediateThreadProc+0x49
01b1ffec 00000000 79f710dd 000bcbf0 00000000 kernel32!BaseThreadStart+0x34&lt;/PRE&gt;
&lt;P&gt;Thread&amp;nbsp;15 however is just&amp;nbsp;a regular .net worker thread waiting for work, and as such it is not pumping messages so thread 19 (finalizer) will be indefinitely blocked in GetToSTA. &lt;/P&gt;
&lt;P&gt;The symptom is very very similar to that explained here &lt;A href="http://support.microsoft.com/?id=828988" mce_href="http://support.microsoft.com/?id=828988"&gt;http://support.microsoft.com/?id=828988&lt;/A&gt;&amp;nbsp;and in this kb the reason for the issue is that the main thread is configured with the attribute [STAThread] and the suggested solution is to change this to [MTAThread] or to manually pump messages using Thread.CurrentThread.Join(100), neither of which really apply in an ASP.NET application. &lt;/P&gt;
&lt;P&gt;The problem in ASP.NET is that the first CLR threadpool worker thread is never initialized for COM+ so if someone instantiates a component there that calls CoInitialize, the thread can become an STA thread and cause this type of blocking...&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Solution:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;A &lt;A href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;928569" mce_href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;928569"&gt;hotfix&lt;/A&gt; was recently released which changes this behavior, so if you run into this issue you can install that.&amp;nbsp; If you also have a lot of unneccesary finalizers like in this particular case, I would recommend that you take care of them since it causes a lot of unneccessary memory usage and higher CPU in GC because of the amount of collections that have to be done to release them and the amount of data the GC has to work through.&lt;/P&gt;
&lt;P&gt;Laters all,&lt;/P&gt;
&lt;P&gt;Tess&lt;/P&gt;&lt;!-- Begin survey for blog post 62 --&gt;&lt;BR&gt;&lt;BR&gt;
&lt;P&gt;
&lt;SCRIPT language=JavaScript&gt;
&lt;!--


if(window.location=="http://blogs.msdn.com/tess/pages/tess-blog-test-page.aspx#tesssurvey62")
{
    document.write("&lt;b&gt;&lt;a name=\"tesssurvey62\"&gt;Thank you for your response.&lt;/a&gt;&lt;/b&gt;");
}
else
{
    document.write("Did this blog post help you resolve a problem?&lt;br&gt;&lt;br&gt;");
    document.write("&lt;a href=\"http://tess.members.winisp.net/survey/submitsurvey.asp?solvedissue=Yes&amp;blogid=62\"&gt;&lt;b&gt;Yes&lt;/b&gt;&lt;/a&gt; | ");
    document.write("&lt;a href=\"http://tess.members.winisp.net/survey/submitsurvey.asp?solvedissue=No&amp;blogid=62\"&gt;&lt;b&gt;No&lt;/b&gt;&lt;/a&gt;");
}


//--&gt;
&lt;/SCRIPT&gt;
&lt;/P&gt;&lt;BR&gt;&lt;BR&gt;&lt;!-- End survey for blog post 62 --&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7322868" width="1" height="1"&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=18544"&gt;</description><author>If broken it is, fix it you should</author><pubDate>2008-01-30T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>Active Objects and Futures</title><link>http://softlogger.com/18626/Design-Architecture/active-objects-and-futures.aspx</link><description>&lt;p&gt;Herb Sutter gave one of my favorite and inspiring presentations.&amp;#160; It is called &amp;quot;The Free Lunch is Over&amp;quot;.&amp;#160; The original article can be found &lt;a href="http://www.gotw.ca/publications/concurrency-ddj.htm"&gt;here&lt;/a&gt;.&amp;#160; My first encounter though came from his &lt;a href="http://www.pluralsight.com/blogs/hsutter/archive/2005/10/25/15903.aspx"&gt;PDC presentation&lt;/a&gt; and highly recommend viewing that as well.&lt;/p&gt;  &lt;p&gt;The part that interested me the most about the talk was two new threading abstractions I hadn't encountered before.&amp;#160; Future's and ActiveObjects.&amp;#160; One of the basic premise is that concurrency should be grep`able and somewhat declarative.&amp;#160; The act of calling a method on a background thread and later waiting for it to complete should be simple, not complicated.&amp;#160; &lt;/p&gt;  &lt;p&gt;Asynchronous programming is one of my favorite aspects of computing.&amp;#160; What interests me the most is how asynchronous programming can be useful for UI.&amp;#160; My biggest pet peeve is when UI hangs because an operation call, or network operation takes too long.&amp;#160; Why not make multi-threading easy and give users a way to cancel out of these operations???&amp;#160; Or start loading on the background thread instead of waiting for the user to perform a specific.&amp;#160; Hopefully over the next month or so I'll lay out some utilities and classes building on Futures and Active Objects that will do precisely this.&lt;/p&gt;  &lt;p&gt;Future's are actions where work can be done now, but the result is not needed until a future time.&amp;#160; Work occurs on a separate thread and the results can be easily joined once work is complete.&lt;/p&gt;  &lt;pre class="code"&gt;            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; f = &lt;span style="color: rgb(43,145,175)"&gt;Future&lt;/span&gt;.Create(() =&amp;gt; LongCalculation());
            &lt;span style="color: rgb(0,128,0)"&gt;// ...
&lt;/span&gt;            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; result = f.Wait();&lt;/pre&gt;

&lt;p&gt;Future's are now exposed via the &lt;a href="http://blogs.msdn.com/pfxteam/archive/2007/11/29/6558413.aspx"&gt;Parallel Extension&lt;/a&gt; team's work.&amp;#160; You can download the CTP off of their web site and get to work. &lt;/p&gt;

&lt;p&gt;ActiveObjects are objects which only expose Asynchronous functions where the return value is exposed as a Future.&amp;#160; So instead of &lt;/p&gt;

&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; GetName()&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;You would have&lt;/p&gt;

&lt;pre class="code"&gt;        &lt;span style="color: rgb(43,145,175)"&gt;Future&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt; GetName()&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;An ActiveObject essentially lives on or owns a thread.&amp;#160; All operations are queued up and processed one at a time.&amp;#160; Since only one action at a time can be executing the object internals don't have to use locks or consider many types of race conditions.&amp;#160; In fact if your return types are immutable a great many threading concerns go out the window.&amp;#160; Yet all of the calls are inherently asynchronous so callers can get the result only when they are needed.&amp;#160; The best of both worlds.&amp;#160; &lt;/p&gt;

&lt;p&gt;Both of these provide significant advantages over the &amp;quot;lock before use&amp;quot; patterns.&amp;#160; In my experience I find these to be hard to maintain and lead to difficult to track down bugs.&amp;#160; I can't tell you how many times I've gone through someone else's code, or even my own, and wondered ...&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Did they forget to lock here or is this an optimization?&lt;/li&gt;

  &lt;li&gt;Is a join needed here or can these terminate at separate times?&lt;/li&gt;

  &lt;li&gt;OK I need to touch that variable, can it be accessed in multiple threads or is it safe? &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Futures/Active Objects on the other hand are a bit more declarative and straight forward to understand than plain old locks.&amp;#160; They allow you to do away with many uses of plain old locking.&amp;#160; Don't confuse this with me saying they are a cure all for threading.&amp;#160; They're not.&amp;#160; But in my experiences I've found them to be a significant upgrade.&amp;#160; &lt;/p&gt;

&lt;p&gt;Over the next month or so I'll be laying out the design for a basic ActiveObject implementation.&amp;#160; We will likely have to deviate off of the Parrallel Extension work to get certain behaviors but the concepts map well.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7298431" width="1" height="1"&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=18626"&gt;</description><author>jaredpars WebLog</author><pubDate>2008-01-29T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>Design and Implementation - Episode 2</title><link>http://softlogger.com/18702/Design-Architecture/design-and-implementation--episode-2.aspx</link><description>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;a href="http://www.pluralsight.com/blogs/tewald"&gt;Tim&lt;/a&gt; and I sat down and recorded our second episode of "Design and Implementation", our occasional podcast. In this episode, we discuss &lt;a href="http://pluralsight.com/blogs/craig/archive/2008/01/23/50030.aspx"&gt;the newly-launched MTPS REST API&lt;/a&gt;. &lt;/div&gt;
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;/div&gt;
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;Grab the epsiode here: &lt;a href="http://pluralsight-free.s3.amazonaws.com/craig-andera/design-and-implementation/002-MtpsREST.mp3"&gt;Design and Implementation Episode 2 (MP3, 33MB)&lt;/a&gt;. &lt;/div&gt;
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;/div&gt;
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;If you missed our first episode, get it &lt;a href="http://pluralsight.com/blogs/craig/archive/2007/12/19/49483.aspx"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;img src ="http://pluralsight.com/blogs/craig/aggbug/50031.aspx" width = "1" height = "1" /&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=18702"&gt;</description><author>CraigBlog</author><pubDate>2008-01-23T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>Modularity Guidance Bundle Screencast Video - Build Pluggable ASP.NET Web Applications</title><link>http://softlogger.com/18557/Design-Architecture/modularity-guidance-bundle-screencast-video--build-pluggable-asp-net-web-applications.aspx</link><description>&lt;H1&gt;&lt;FONT face=Verdana&gt;Modularity Guidance Bundle Screencast Video - Build Pluggable ASP.NET Web Applications&lt;/FONT&gt;&lt;/H1&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;by &lt;A href="http://www.davidhayden.com/"&gt;David Hayden&lt;/A&gt;, &lt;A href="http://www.davidhayden.com/"&gt;Florida ASP.NET Developer&lt;/A&gt;, Tag: &lt;A href="http://davidhayden.com/blog/dave/category/57.aspx?Show=All"&gt;Web Client Software Factory&lt;/A&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.pnpguidance.net/Screencast/ModularityBundleScreencastWCSFCreateModularASPNETWebApplications.aspx"&gt;&lt;IMG alt="Modularity Bundle Screencast" src="/davidhayden/images/data/modularitybundlescreencast.jpg" align=right border=0&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt;The Microsoft Patterns &amp;amp; Practices Team released the &lt;A href="http://www.pnpguidance.net/Tag/ModularityBundle.aspx"&gt;Modularity Guidance Bundle&lt;/A&gt; and I went ahead and put together a video that discusses the Modularity Bundle Quickstart in detail from the standpoint of creating modular web client applications using the &lt;A href="http://www.pnpguidance.net/Tag/CompositeWebApplicationBlock.aspx"&gt;Composite Web Application Block&lt;/A&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;&lt;A href="http://www.pnpguidance.net/Screencast/ModularityBundleScreencastWCSFCreateModularASPNETWebApplications.aspx"&gt;Modularity Bundle Screencast in WCSF - Create Modular ASP.NET Web Applications&lt;/A&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;The screencast highlights:&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=Verdana size=2&gt;The Composite Web Application Block ( CWAB ).&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Verdana size=2&gt;Business Modules and Foundation Modules.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Verdana size=2&gt;WebModuleEnumerator and ModuleLoader Services.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Verdana size=2&gt;Custom Module Configuration Sections.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Verdana size=2&gt;ModuleInitializer and Adding Global and Module Services.&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;So far there are 16&amp;nbsp;&lt;A href="http://www.pnpguidance.net/Screencasts.aspx"&gt;Patterns &amp;amp; Practices Screencasts&lt;/A&gt;, and I have a few that I will publish after my talks at the &lt;A href="http://www.pnpguidance.net/FreeDayPatternsAndPracticesTampa2008.aspx"&gt;Day of Patterns &amp;amp; Practices&lt;/A&gt; and the &lt;A href="http://www.flacodebrew.net/Post/SouthFloridaCodeCampSaturdayFebruary22008.aspx"&gt;South Florida Code Camp&lt;/A&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;I hope you enjoy it.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;&lt;img src ="http://davidhayden.com/blog/dave/aggbug/3444.aspx" width = "1" height = "1" /&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=18557"&gt;</description><author>David Hayden - Florida .NET Developer - C# and SQL Server</author><pubDate>2008-01-23T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>The Real Value of Service Oriented Architecture (SOA)</title><link>http://softlogger.com/17912/Design-Architecture/the-real-value-of-service-oriented-architecture-soa.aspx</link><description>Why SOA isn't just another spot on your buzz-word bingo card.&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=17912"&gt;</description><author>A .NET Architecture, Design &amp;amp; Development Journal</author><pubDate>2008-01-11T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>Partial Classes  and future-proof vindication</title><link>http://softlogger.com/17714/Design-Architecture/partial-classes-and-future-proof-vindication.aspx</link><description>&lt;p&gt;A common question is "How can my tool crack the PDB to automatically determine what source file / line number a .NET class is defined in?"&amp;nbsp; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;It's a trick question.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;There's a problem with the question. A .NET class may not be defined at a single source file / line number. &lt;/p&gt; &lt;p&gt;How should you specify what source file and line number a .NET class is defined in?&amp;nbsp; Ok, that's easy for C# 1.0 since the entire class is contained in a single source file, and you could even say the line number is where the 'class' keyword appears. &lt;/p&gt; &lt;p&gt;In that case, you could use a C# 1.0 specific technique (such as grepping source files). But managed PDBs are targeted more generally at the IL level, and so the design tried to avoid getting tied to specific C# or other language semantics. &lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/jmstall/archive/2005/08/25/pdb2xml.aspx"&gt;Managed PDBs&lt;/a&gt; provide source mappings for executable IL opcodes within a function body. That has well defined semantics. An executable opcode can map to an instruction address, which can map to a source line. But mapping .NET class declarations to line numbers as used generally across different .NET languages is not so clear...&lt;/p&gt; &lt;p&gt;When people asked this back in the C# 1.0 days, we'd emphasize the issue at the IL level. But since it wasn't a problem in C# 1.0, there wasn't a killer counter-example. All of obvious examples made it appear that classes had a well defined file/line number.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Corner cases and Future-proofing&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We'd suggest that they could approximate the answer by just using the source mapping for an arbitrary method in the class. Of course, this wasn't 100%. &lt;/p&gt; &lt;p&gt;Maybe the class was empty or didn't have any method bodies. Maybe the class was produced from some less common codegen construct, in which case people didn't want to run the query anyways. Maybe the functions were defined across multiple files.&amp;nbsp;&amp;nbsp; You could even force that with the #line directive. But folks asking usually considered these to be insignificant corner cases. There were certainly a lot of corner cases, but unless you really understood the problem space, it was never really convincing; the corner cases just seemed like excuses. ("oh, we don't need to handle such an obscure case. We just need a solution that works for the mainline cases")&amp;nbsp; &lt;/p&gt; &lt;p&gt;One could also view our obstinance of adhering to the protocol as defending the invariants and &lt;a href="http://blogs.msdn.com/jmstall/archive/2006/08/21/buzzword_bingo.aspx"&gt;future-proofing&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;The vindication&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;C# 2.0 introduced &lt;a href="http://msdn2.microsoft.com/en-us/library/wa80x488.aspx"&gt;Partial Classes&lt;/a&gt;, which provided 1st-class mainline language support for splitting a class across multiple source locations. And then the default designers leveraged this so that you could write your user code in foo.cs and auto-generated code for your class would go in a file like foo.designer.cs. So now there was a mainstream common case that showing that a class may not be defined at a single source file / line number.&amp;nbsp; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7051467" width="1" height="1"&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=17714"&gt;</description><author>Mike Stalls blog                                                                                    </author><pubDate>2008-01-10T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>Add or remove the www sub domain</title><link>http://softlogger.com/17692/Design-Architecture/add-or-remove-the-www-sub-domain.aspx</link><description>&lt;p&gt;
Most websites needs a policy for handling the www sub domain because of SEO. It doesn&amp;rsquo;t matter if you redirect all requests coming&amp;nbsp;from &lt;em&gt;http://www.example.com&lt;/em&gt; to &lt;em&gt;http://example.com&lt;/em&gt; or the other way around. The important thing is that you do one of them. Otherwise search engines will punish you for duplicate content. 
&lt;/p&gt;
&lt;p&gt;
This feature is built in to &lt;a href="http://dotnetblogengine.net"&gt;BlogEngine.NET&lt;/a&gt; and it allows you to either enforce the use of www or to remove it. It&amp;rsquo;s an HttpModule that handles these two scenarios and I&amp;rsquo;ve pulled it out of BlogEngine.NET and polished it so it can be used in any ASP.NET web application. 
&lt;/p&gt;
&lt;h2&gt;The code&lt;/h2&gt;
&lt;p&gt;
This is the bit that handles the incoming request and either removes or enforces the www sub domain based on a web.config &lt;em&gt;appSetting&lt;/em&gt;. 
&lt;/p&gt;
&lt;div style="background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: Consolas"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Handles the BeginRequest event of the context control.&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;param name=&amp;quot;sender&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The source of the event.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;param name=&amp;quot;e&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;see cref=&amp;quot;System.EventArgs&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt; instance containing the event data.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; context_BeginRequest(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e) 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{ 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; rule = &lt;span style="color: #2b91af"&gt;ConfigurationManager&lt;/span&gt;.AppSettings.Get(&lt;span style="color: #a31515"&gt;&amp;quot;WwwRule&amp;quot;&lt;/span&gt;); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt; context = (sender &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;HttpApplication&lt;/span&gt;).Context; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (context.Request.HttpMethod != &lt;span style="color: #a31515"&gt;&amp;quot;GET&amp;quot;&lt;/span&gt; || context.Request.IsLocal) 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt;; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (context.Request.PhysicalPath.EndsWith(&lt;span style="color: #a31515"&gt;&amp;quot;.aspx&amp;quot;&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StringComparison&lt;/span&gt;.OrdinalIgnoreCase)) 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; { 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; url = context.Request.Url.ToString(); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (url.Contains(&lt;span style="color: #a31515"&gt;&amp;quot;://www.&amp;quot;&lt;/span&gt;) &amp;amp;&amp;amp; rule == &lt;span style="color: #a31515"&gt;&amp;quot;remove&amp;quot;&lt;/span&gt;) 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; RemoveWww(context); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (!url.Contains(&lt;span style="color: #a31515"&gt;&amp;quot;://www.&amp;quot;&lt;/span&gt;) &amp;amp;&amp;amp; rule == &lt;span style="color: #a31515"&gt;&amp;quot;add&amp;quot;&lt;/span&gt;) 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; AddWww(context); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; } 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
} 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Adds the www subdomain to the request and redirects.&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; AddWww(&lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt; context) 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{ 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; url = context.Request.Url.ToString().Replace(&lt;span style="color: #a31515"&gt;&amp;quot;://&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;://www.&amp;quot;&lt;/span&gt;); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; PermanentRedirect(url, context); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
} 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;readonly&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Regex&lt;/span&gt; _Regex = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Regex&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;(http|https)://www\\.&amp;quot;&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;RegexOptions&lt;/span&gt;.IgnoreCase | &lt;span style="color: #2b91af"&gt;RegexOptions&lt;/span&gt;.Compiled); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Removes the www subdomain from the request and redirects.&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; RemoveWww(&lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt; context) 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{ 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; url = context.Request.Url.ToString(); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (_Regex.IsMatch(url)) 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; { 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &amp;nbsp; url = _Regex.Replace(url, &lt;span style="color: #a31515"&gt;&amp;quot;$1://&amp;quot;&lt;/span&gt;); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &amp;nbsp; PermanentRedirect(url, context); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; } 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red128\green128\blue128;\red255\green255\blue255;\red0\green128\blue0;\red0\green0\blue255;\red0\green0\blue0;\red43\green145\blue175;\red255\green0\blue0;\red163\green21\blue21;}??\fs20 \cf1 ///\cf3  \cf1 &amp;lt;summary&amp;gt;\par ??///\cf3  Sends permanent redirection headers (301)\par ??\cf1 ///\cf3  \cf1 &amp;lt;/summary&amp;gt;\par ??\cf4 private\cf0  \cf4 static\cf0  \cf4 void\cf0  PermanentRedirect(\cf4 string\cf0  url, \cf6 HttpContext\cf0  context)\par ??\{\par ??\tab context.Response.Clear();\par ??\tab context.Response.StatusCode = \cf7 301\cf0 ;\par ??\tab context.Response.AppendHeader(\cf8 "location"\cf0 , url);\par ??\tab context.Response.End();\par ??\}}
--&gt;
&lt;/p&gt;
&lt;div style="background: white none repeat scroll 0% 50%; font-family: Consolas; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Sends permanent redirection headers (301)&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; PermanentRedirect(&lt;span style="color: blue"&gt;string&lt;/span&gt; url, &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt; context)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; context.Response.Clear();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; context.Response.StatusCode = &lt;span style="color: red"&gt;301&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; context.Response.AppendHeader(&lt;span style="color: #a31515"&gt;&amp;quot;location&amp;quot;&lt;/span&gt;, url);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; context.Response.End();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;
Download the HttpModule below and drop it in your &lt;em&gt;App_Code&lt;/em&gt; folder. Then register the module in the web.config&amp;rsquo;s &lt;em&gt;system.web&lt;/em&gt; section like so: 
&lt;/p&gt;
&lt;p&gt;
&amp;lt;httpModules&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;add type=&amp;quot;WwwSubDomainModule&amp;quot; name=&amp;quot;WwwSubDomainModule&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/httpModules&amp;gt; 
&lt;/p&gt;
&lt;p&gt;
You also need to add an appSetting like so: 
&lt;/p&gt;
&lt;p&gt;
&amp;lt;appSettings&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;!-- Values can be &amp;#39;add&amp;#39; or &amp;#39;remove&amp;#39; --&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;add key=&amp;quot;WwwRule&amp;quot; value=&amp;quot;add&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/appSettings&amp;gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;a rel="enclosure" href="http://blog.madskristensen.dk/file.axd?file=WwwSubDomainModule.zip"&gt;WwwSubDomainModule.zip (1,23 kb)&lt;/a&gt; 
&lt;/p&gt;
&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=17692"&gt;</description><author>.NET slave</author><pubDate>2008-01-09T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>MVP Bundle Screencast - Learn ASP.NET MVP Design Pattern Using WCSF and Without WCSF</title><link>http://softlogger.com/14993/Design-Architecture/mvp-bundle-screencast--learn-asp-net-mvp-design-pattern-using-wcsf-and-without-wcsf.aspx</link><description>&lt;H1&gt;&lt;FONT face=Verdana&gt;MVP Bundle Screencast - Learn ASP.NET MVP Design Pattern Using WCSF and Without WCSF&lt;/FONT&gt;&lt;/H1&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;by &lt;A href="http://www.davidhayden.com/"&gt;David Hayden&lt;/A&gt; ( &lt;A href="http://www.davidhayden.com/"&gt;Florida&amp;nbsp;Web&amp;nbsp;Developer&lt;/A&gt; ), Filed: &lt;A href="http://davidhayden.com/blog/dave/category/57.aspx?Show=All"&gt;Web Client Software Factory&lt;/A&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.pnpguidance.net/Screencast/MVPBundleScreencastWCSFModelViewPresenterDesignPattern.aspx"&gt;&lt;IMG alt="MVP Bundle Screencast" src="/davidhayden/images/data/mvpbundle.jpg" align=right border=0&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt;For those of you interested in learning the &lt;/FONT&gt;&lt;A href="http://www.pnpguidance.net/Tag/ModelViewPresenter.aspx"&gt;&lt;FONT face=Verdana size=2&gt;Model View Presenter&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt; Design Pattern in ASP.NET, the Microsoft Patterns &amp;amp; Practices Team released an &lt;/FONT&gt;&lt;A href="http://www.pnpguidance.net/Tag/MVPBundle.aspx"&gt;&lt;FONT face=Verdana size=2&gt;MVP Bundle&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt; as a part of the &lt;/FONT&gt;&lt;A href="http://www.pnpguidance.net/Category/WebClientSoftwareFactory.aspx"&gt;&lt;FONT face=Verdana size=2&gt;Web Client Software Factory&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt; v2.0.&amp;nbsp;The MVP Bundle&amp;nbsp;contains two quickstart examples&amp;nbsp;with guidance on&amp;nbsp;implementing the MVP Design Pattern with and without the &lt;/FONT&gt;&lt;A href="http://www.pnpguidance.net/Tag/CompositeWebApplicationBlock.aspx"&gt;&lt;FONT face=Verdana size=2&gt;Composite Web Application Block&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt;, which&amp;nbsp;among other things, provides &lt;/FONT&gt;&lt;A href="http://www.pnpguidance.net/Tag/DependencyInjection.aspx"&gt;&lt;FONT face=Verdana size=2&gt;Dependency Injection&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt; services using Object Builder.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;I created an &lt;/FONT&gt;&lt;A href="http://www.pnpguidance.net/Screencast/MVPBundleScreencastWCSFModelViewPresenterDesignPattern.aspx"&gt;&lt;FONT face=Verdana size=2&gt;MVP Bundle Screencast&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt; that walks you through the two quickstart samples in the MVP Bundle, pointing out all the cool features in the WCSF&amp;nbsp;to help with Model View Presenter as well as all the 3rd party Dependency Injection and Mock Frameworks that you can use if not using the WCSF and Composite Web Application Block.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;If you want to learn more about implementing the Model View Presenter Design Pattern in the Web Client Software Factory after viewing the screencast, I recommend the following screencast which talks more about the View-Presenter Pattern in the WCSF:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.pnpguidance.net/Screencast/ViewPresenterPatternWebClientSoftwareFactoryScreencast.aspx"&gt;&lt;FONT face=Verdana size=2&gt;View-Presenter Pattern in Web Client Software Factory Screencast&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;The MVP Bundle Screencast&amp;nbsp;went a little longer than expected&amp;nbsp;at 29 minutes, but if you are new to the WCSF and/or MVP in ASP.NET, I think it will be worth watching:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.pnpguidance.net/Screencast/MVPBundleScreencastWCSFModelViewPresenterDesignPattern.aspx"&gt;&lt;FONT face=Verdana size=2&gt;MVP Bundle Screencast - WCSF v2.0 Model View Presenter Design Pattern&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;Enjoy and Happy Holidays!&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;&lt;img src ="http://davidhayden.com/blog/dave/aggbug/3419.aspx" width = "1" height = "1" /&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=14993"&gt;</description><author>David Hayden - Florida .NET Developer - C# and SQL Server</author><pubDate>2007-12-22T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>Code Better With Design Patters in .Net Training Thoughts...</title><link>http://softlogger.com/14498/Design-Architecture/code-better-with-design-patters-in-net-training-thoughts-.aspx</link><description>&lt;p&gt;This past week I attended the &lt;a href="http://www.develop.com/us/training/course.aspx?id=663"&gt;Code Smarter with Design Patterns in .Net&lt;/a&gt; course given by &lt;a href="http://www.develop.com/"&gt;Developmentor&lt;/a&gt; and I wanted to share some thoughts about it...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Instructor&lt;br&gt;&lt;/strong&gt;As I'm sure you heard or seen, sometimes it is a hit or miss game with the level of a trainers experience. Sometimes they are a day ahead of you, learning as they go. Or, as seems to be the rule with Developmentor, they are very experienced, have been coding for years and generally just know their stuff.&lt;/p&gt; &lt;p&gt;Kevin Jones, the instructor for Code Better With Design Patters in .Net, was not only a great presenter but had decades of real world experience (err... sorry Kevin... I meant "a number of years of experience..." yeah... that... ;). And best of all that experience was across many technologies, trends and programming languages. This gave a depth to his lectures that only comes with experience, knowledge and wisdom. &lt;/p&gt; &lt;p&gt;He was able to seemingly easily translate that experience and knowledge and present it to us. This provided a back story and depth to the material. Not just a "here is the pattern," but "here is the pattern and here's why this has become important and the problems that it was evolved to solve..."&lt;/p&gt; &lt;p&gt;Kevin was also very flexible in how he presented the material, modifying it on the fly in order to adapt to the experience levels in the class or to fit it into our schedules (flight, commute, etc)&lt;/p&gt; &lt;p&gt;You've heard, "those who can't do, teach"? That was far from the case with Kevin (and the other Developmentor instructors I've met in the past). He really knew his stuff and it showed.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Class Environment&lt;br&gt;&lt;/strong&gt;If you go to a Los Angeles Developmentor course, bring a jacket... I've attended two classes there and both times it was cold in the classroom (so cold the first time the Developmentor guys went out and bought sweatshirts for all attendees with the text, "Developmentor is cool"... LOL. Got to love that kind of humor...)&lt;/p&gt; &lt;p&gt;Besides that, I dig Developmentor courses. The rooms are good, the computers are always setup and working, the staff is professional and friendly and the lobby/gathering area always stocked with drinks, snacks and stuff ;)&lt;/p&gt; &lt;p&gt;Developmentor usually has small class sizes, which means you quickly develop a learning relationship with every one. This course was the most attended of any past course I've gone too, having 12 attendees. &lt;/p&gt; &lt;p&gt;This near one-on-one training situation is just one reason I find myself returning so often to Developmentor...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Course Content&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I've been seeing the buzz on patterns for many years. I've done some reading and bought some books, but never got the "fire." Never really saw how they would directly help me solve my development problems. Having someone walk me thought it, provide the depth that I'd not seen before was just the push I needed.&lt;/p&gt; &lt;p&gt;The funny thing about this, is by the end of the class I saw that I've already been using patterns for many years. Reinventing the wheel over and over again. sigh...&lt;/p&gt; &lt;p&gt;A couple times a day I'd find myself thinking, "I done that before... I've built using singleton, factory, proxy, facade, strategy, etc, patterns for years... I just didn't know it. Nor, now that I see it, did I build them quite right..."&lt;/p&gt; &lt;p&gt;One thing I really liked about this course was that it wasn't about technology, but how to use existing technology (C#/.Net 2.0 with patterns) to provide better answers to the problems I have today. How to be a better developer... How to make your coding life easier... How to provide more professional solutions that will be easier to maintain and improve over time. &lt;/p&gt; &lt;p&gt;You can only present and learn so much in 32 hours, but with the interactive nature of the training, having someone who has "been there, done that," the knowledge gained was multiplied and sunk in deeper.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Okay, okay... I know I'm gushing a little. All was not perfect. I think the parking is a pain (park in this building, then that building and then on the last day park in this building, etc). I HATED the drive to it (driving everyday from Simi Valley to LAX on the freeway from hell, aka the 405, was just pure pain). I wish it was longer, and covered enterprise patterns (like MVC, etc). And I wish there were a VB.Net version (or at least VB.Net labs). But in the end those were little things...&lt;/p&gt; &lt;p&gt;All in all, I felt this course was money very well spent and one that I am going to recommend to my peers (and of course to you as well&amp;nbsp; :).&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Related Past Post XRef:&lt;br&gt;&lt;a href="http://coolthingoftheday.blogspot.com/2007/12/i-be-mostly-offline-next-few-days.html"&gt;I'll be mostly offline the next few days...&lt;/a&gt;&lt;/p&gt;  &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/coolthingoftheday?a=UcE3QrC"&gt;&lt;img src="http://feeds.feedburner.com/~f/coolthingoftheday?i=UcE3QrC" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/coolthingoftheday?a=BwsxTWC"&gt;&lt;img src="http://feeds.feedburner.com/~f/coolthingoftheday?i=BwsxTWC" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/coolthingoftheday?a=qDgUbOC"&gt;&lt;img src="http://feeds.feedburner.com/~f/coolthingoftheday?i=qDgUbOC" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/coolthingoftheday/~4/201265712" height="1" width="1"/&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=14498"&gt;</description><author>Gregs Cool [Insert Clever Name] of the Day</author><pubDate>2007-12-17T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>iPhone Tops Time's List Of Top 10 Gadgets Of 2007</title><link>http://softlogger.com/14390/Design-Architecture/iphone-tops-time-s-list-of-top-10-gadgets-of-2007.aspx</link><description>The iPhone has landed at #1 on Time's list of Top 10 Gadgets of 2007.The iPhone changed the way we think about how mobile media devices should look, feel and perform. The design is exceptional inside...&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=14390"&gt;</description><author>iPod Hacks</author><pubDate>2007-12-17T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>Return vs. Finally (2)</title><link>http://softlogger.com/14431/Design-Architecture/return-vs-finally-2.aspx</link><description>&lt;p&gt;The Return statement and finally have competition. Both can are the "last" thing to execute when a function exits, so which of them is really last? I blogged about this &lt;a href="http://blogs.msdn.com/jmstall/archive/2006/10/05/finally_5F00_vs_5F00_return.aspx"&gt;before&lt;/a&gt; regarding C#'s semantics setting data. Now I'll compare some interesting differences between C# and &lt;a href="http://blogs.msdn.com/jmstall/archive/2007/11/17/learning-python.aspx"&gt;Python&lt;/a&gt;. &lt;p&gt;Who wins if you set them up in direct competition like this (non-exceptional path):&lt;br&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; f1()
    {
        &lt;span style="color: rgb(0,0,255)"&gt;try
&lt;/span&gt;        {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 10;
        }
        &lt;span style="color: rgb(0,0,255)"&gt;finally
&lt;/span&gt;        {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 5;
        }
    }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;or this (the exceptional path):&lt;br&gt;&lt;pre class="code"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; f2()
    {
        &lt;span style="color: rgb(0,0,255)"&gt;try
&lt;/span&gt;        {
            &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(0,128,128)"&gt;Exception&lt;/span&gt;();
        }
        &lt;span style="color: rgb(0,0,255)"&gt;finally
&lt;/span&gt;        {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 5;
        }
    }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&amp;nbsp; &lt;p&gt;There are multiple intelligent ways a language design could answer this. 
&lt;p&gt;&lt;strong&gt;C#'s answer&lt;/strong&gt;: &lt;strong&gt;Illegal&lt;/strong&gt;
&lt;p&gt;In C#, this is just illegal. Returns are forbidden in finally clauses. This nicely just avoids the whole problem by refusing to let you write such potentially ambiguous and confusing code.&amp;nbsp; (&lt;a href="http://msdn2.microsoft.com/en-us/library/0hbbzekw(vs.80).aspx"&gt;CS0157&lt;/a&gt;: "Control cannot leave the body of a finally clause"). And if a consensus emerges down the road that there really is a clear "right" answer, C# can always make it legal with the "right" semantics. 
&lt;p&gt;&lt;strong&gt;IL's answer: Illegal&lt;/strong&gt;
&lt;p&gt;The underlying CLR's IL instruction provides try/catch/finally and branching opcodes. The only branching opcode out of a finally is '&lt;a href="http://msdn2.microsoft.com/en-us/library/system.reflection.emit.opcodes.endfinally(VS.71).aspx"&gt;endfinally&lt;/a&gt;', which jumps to the end of the finally block. You can't return / branch out of a finally. (See VER_E_RET_FROM_HND=0x80131845 in CorError.h).
&lt;p&gt;Since .NET languages compile to IL, it may be natural for a language to have the same semantics as the IL instructions it compiles to.&amp;nbsp; It's not surprising that C# has the same restrictions as the underlying IL&amp;nbsp; instruction set here.&amp;nbsp; However, a .NET language&amp;nbsp; can have more clever opcode usage to provide their own semantics.
&lt;p&gt;&amp;nbsp; &lt;p&gt;&lt;strong&gt;Python's answer&lt;/strong&gt;: &lt;strong&gt;Legal&lt;/strong&gt;
&lt;p&gt;In Python, return inside of finally is actually allowed.&amp;nbsp; &lt;/p&gt;
&lt;table border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; def f1():
...   try:
...     return 10
...   finally:
...     return 5
...
&amp;gt;&amp;gt;&amp;gt; f1()
5
&amp;gt;&amp;gt;&amp;gt; def f2():
...   try:
...     raise Exception # like 'throw'
...   finally:
...     return 5
...
&amp;gt;&amp;gt;&amp;gt;
&amp;gt;&amp;gt;&amp;gt; f2()
5
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&amp;nbsp; &lt;p&gt;In this case, you can see that even on the exceptional path, the return statement will swallow the exception and return a value. 
&lt;p&gt;Note that &lt;a href="http://www.codeplex.com/ironpython"&gt;IronPython&lt;/a&gt; compiles to IL, and still faithfully maintains the python exception semantics here.
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6783786" width="1" height="1"&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=14431"&gt;</description><author>Mike Stalls blog                                                                                    </author><pubDate>2007-12-16T00:00:00</pubDate><category>Design, Architecture</category></item><item><title>.NET Compact Framework WCF and Store and Forward Messaging Webcast</title><link>http://softlogger.com/14231/Design-Architecture/net-compact-framework-wcf-and-store-and-forward-messaging-webcast.aspx</link><description>&lt;P&gt;Just a quick note to let everyone know that I'll be giving a &lt;A href="http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032358593&amp;amp;EventCategory=4&amp;amp;culture=en-US&amp;amp;CountryCode=US"&gt;Webcast&lt;/A&gt; this Wednesday (12-Dec) talking about Windows Communication Foundation as it's implemented on Windows Mobile with a focus on Store-and-Forward messaging. Store-and-Forward messaging is a .NET CF extension to WCF that significantly simplifies communication between mobile devices because it eliminates the need for the source and destination devices to be online at the same time. The sending device can send the message at anytime - if the receiving device is online, the device receives the message immediately; otherwise, the receiving device receives the message the next time the receiving device comes online. &lt;/P&gt;
&lt;P&gt;Please &lt;A href="http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032358593&amp;amp;EventCategory=4&amp;amp;culture=en-US&amp;amp;CountryCode=US"&gt;join me on Wednesday&lt;/A&gt; for a look at the architecture of .NET CF WCF Store-and-Forward messaging and a demonstration of how to build applications that take advantage of it.&lt;/P&gt;
&lt;P&gt;The &lt;A href="http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032358593&amp;amp;EventCategory=4&amp;amp;culture=en-US&amp;amp;CountryCode=US"&gt;Webcast&lt;/A&gt; will be broadcast live on Wednesday, 12-December at 11:00 AM PST, 2:00 PM EST, 1900 UTC. I hope to see you there.&lt;/P&gt;&lt;img src ="http://pluralsight.com/blogs/jimw/aggbug/49389.aspx" width = "1" height = "1" /&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=14231"&gt;</description><author>You Can Take it With You</author><pubDate>2007-12-10T00:00:00</pubDate><category>Design, Architecture</category></item></channel></rss>