<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Kim Hamilton</title><subtitle type="html" /><id>http://blogs.msdn.com/kimhamil/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/kimhamil/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2008-03-08T01:42:00Z</updated><entry><title>Advanced resource debugging with Resview</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2009/03/06/advanced-resource-debugging-with-resview.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2009/03/06/advanced-resource-debugging-with-resview.aspx</id><published>2009-03-06T22:11:00Z</published><updated>2009-03-06T22:11:00Z</updated><content type="html">&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;In an &lt;/FONT&gt;&lt;A href="http://blogs.msdn.com/bclteam/archive/2009/02/16/working-with-the-resourcemanager-kim-hamilton.aspx" mce_href="http://blogs.msdn.com/bclteam/archive/2009/02/16/working-with-the-resourcemanager-kim-hamilton.aspx"&gt;&lt;FONT face=Calibri size=3&gt;earlier blog about resource fallback essentials&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt;, I said that the resource diagnostic tool resview is included with the framework sdk. That was wrong – it turns out we previously released resview as a gotdotnet sample, but it’s no longer accessible. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Since resview is helpful in our own investigations, we decided to re-release resview on code gallery &lt;/FONT&gt;&lt;A href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=bcl&amp;amp;DownloadId=4983" mce_href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=bcl&amp;amp;DownloadId=4983"&gt;&lt;FONT face=Calibri size=3&gt;[download resview]&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt;. &lt;/FONT&gt;&lt;/P&gt;
&lt;H1 style="MARGIN: 24pt 0in 0pt"&gt;&lt;FONT face=Cambria color=#365f91 size=4&gt;About Resview&lt;/FONT&gt;&lt;/H1&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Resview looks specifically for resource embedding problems that can result in runtime resource lookup problems. It can tell you about critical errors; for example, if the assembly is missing resources or the embedded resource file name is incorrect. It also gives warnings about best practices – for example, reminding you to include NeutralResourcesLanguagesAttribute.&lt;/FONT&gt;&lt;/P&gt;
&lt;H1 style="MARGIN: 24pt 0in 0pt"&gt;&lt;FONT face=Cambria color=#365f91 size=4&gt;How to use resview&lt;/FONT&gt;&lt;/H1&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;You can run resview on a .resources file, a main assembly, or a satellite assembly. Let’s run resview on assemblies from the &lt;/FONT&gt;&lt;A href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=bcl&amp;amp;DownloadId=4844" mce_href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=bcl&amp;amp;DownloadId=4844"&gt;&lt;FONT face=Calibri size=3&gt;ResourceManagerSample&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt; project, mentioned in the previous blog.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;To view the resources embedded in the main assembly, run “resview Fallback.exe”. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;FONT face=Calibri size=3&gt;To view the resources embedded in a satellite assembly, run “resview FallbackTest.resources.dll” on any of the satellite assemblies.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;FONT face=Calibri size=3&gt;Let’s look at the output when running on the main assembly. I’ve added numbers to the end of interesting lines, which will be described afterwards.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;ResourceManagerSample&amp;gt;resview FallbackTest.exe&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Microsoft (R) Visual .resources Viewer Version 1.83 [CLR version 4.0.20209.0]&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;FallbackTest.exe is a main assembly.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;ResView : warning: This assembly does not have a NeutralResourcesLanguageAttribute.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Using this attribute gives a slight perf optimization for one culture, and &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;is required &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;for localizable ClickOnce apps.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;(1)&lt;o:p&gt;&lt;/o:p&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Public key token: null&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;[This must not be a shipping binary]&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;(2)&lt;o:p&gt;&lt;/o:p&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Processing FallbackStrings.resources...&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;STRONG&gt;(3)&lt;o:p&gt;&lt;/o:p&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Resources from FallbackStrings.resources...&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;greeting = hello&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;eow = weekend&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Found 2 resources in FallbackStrings.resources.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;STRONG&gt;(4)&lt;o:p&gt;&lt;/o:p&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Found 1 resource file, with a total of 2 resources.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Encountered 0 errors, 1 warning.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Total size of all .resources files: 244&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Total length of keys (chars): 11&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Average: 5.5&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Total length of String values (chars): 12&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Average: 6.0&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Number of Strings: 2&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Byte[]'s: 0&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Streams: 0&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Others: 0&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;# of unique Types: 1&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;file est. overhead: 221 bytes&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;110.5 bytes/resource&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;90.6% of the file&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;Output time: 31 ms &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;FONT face=Calibri size=3&gt;This tells us the following:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpFirst style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; LINE-HEIGHT: normal; mso-add-space: auto; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;1.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;The main assembly didn’t use the NeutralResourcesLanguageAttribute. We strongly recommend that you add this attribute. &lt;/FONT&gt;&lt;A href="http://blogs.msdn.com/kimhamil/archive/2008/11/11/what-does-the-neutralresourceslanguageattribute-do.aspx" mce_href="http://blogs.msdn.com/kimhamil/archive/2008/11/11/what-does-the-neutralresourceslanguageattribute-do.aspx"&gt;&lt;FONT face=Calibri size=3&gt;About the NeutralResourcesLanguageAttribute&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; LINE-HEIGHT: normal; mso-add-space: auto; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;2.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;There’s no public key token. This serves as a reminder, in case your assembly needs a strong name.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; LINE-HEIGHT: normal; mso-add-space: auto; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;3.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Resview found an embedded resources file named FallbackStrings.resources.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpLast style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; LINE-HEIGHT: normal; mso-add-space: auto; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;4.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Lists the resources in that file&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: Consolas"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;FONT face=Calibri size=3&gt;In addition to the general diagnostic information resview provides (for example, if the files were named incorrectly), 3 and 4 combined can be useful for debugging resource failures. For example, if you get an error during resource lookup, you can check whether the resources file the ResourceManager is searching for is actually embedded in the assembly. If so, you can check whether the key/value pair is actually in the resources file.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9463314" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author><category term="resources" scheme="http://blogs.msdn.com/kimhamil/archive/tags/resources/default.aspx" /></entry><entry><title>Cleaning up after yourself (Dispose(void) doesn't get called for you)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2008/11/17/cleaning-up-after-yourself-dispose-void-doesn-t-get-called-for-you.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2008/11/17/cleaning-up-after-yourself-dispose-void-doesn-t-get-called-for-you.aspx</id><published>2008-11-18T09:06:00Z</published><updated>2008-11-18T09:06:00Z</updated><content type="html">&lt;P&gt;Despite my large and growing number of Dispose-related blogs, I really don't like writing about Dispose. Or rather, I don't like that Dispose is in such a confusing state that it requires so much reading material. :) But here we are again. I'd like to start posting some of the common Dispose questions I get, in hopes that it will save time for others.&lt;/P&gt;
&lt;P&gt;I got an email asking why StreamWriter's data isn't getting flushed to disk. In their scenario, the problem manifested as a partial file; i.e., the final block wasn't flushed to disk. But they also showed a smaller repro in which no data is flushed to disk.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;using System; &lt;BR&gt;using System.IO; &lt;BR&gt;using System.Threading; &lt;/P&gt;
&lt;P&gt;public class StreamWriterWrapper : &lt;STRONG&gt;IDisposable&lt;/STRONG&gt; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public StreamWriter writer; &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void Main(string[] args) { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StreamWriterWrapper test = new StreamWriterWrapper(@"C:\temp\test.txt"); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; test.writer.WriteLine("some text"); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; test.writer.WriteLine("some more text"); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public StreamWriterWrapper(string filename) { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; writer = new StreamWriter(filename); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void &lt;STRONG&gt;Dispose&lt;/STRONG&gt;() { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; writer.Close(); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;}&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The user's comment was: it looks like .NET isn't calling Dispose for us, even though we implemented IDisposable and provided a Dispose method, and this is why the data isn't getting flushed.&lt;/P&gt;
&lt;P&gt;The user is completely right. And this is a key difference between Dispose and finalization. Dispose(void) doesn't get called for you; your code needs to explicitly call it.&amp;nbsp; This is different than finalization, and since Brian has already written up a great description of this difference, I'll refer you to his blog for more details:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/bclteam/archive/2007/10/30/dispose-pattern-and-object-lifetime-brian-grunkemeyer.aspx" mce_href="http://blogs.msdn.com/bclteam/archive/2007/10/30/dispose-pattern-and-object-lifetime-brian-grunkemeyer.aspx"&gt;http://blogs.msdn.com/bclteam/archive/2007/10/30/dispose-pattern-and-object-lifetime-brian-grunkemeyer.aspx&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9116982" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author><category term="IO" scheme="http://blogs.msdn.com/kimhamil/archive/tags/IO/default.aspx" /><category term="Dispose" scheme="http://blogs.msdn.com/kimhamil/archive/tags/Dispose/default.aspx" /></entry><entry><title>What does the NeutralResourcesLanguageAttribute do?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2008/11/11/what-does-the-neutralresourceslanguageattribute-do.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2008/11/11/what-does-the-neutralresourceslanguageattribute-do.aspx</id><published>2008-11-12T02:44:00Z</published><updated>2008-11-12T02:44:00Z</updated><content type="html">&lt;P&gt;NeutralResourcesLanguageAttribute marks the neutral culture for an assembly. That sounds self-referential, but a full description would require another blog post. To avoid getting bogged down, think of neutral culture roughly as the default language. (Fingers crossed that&amp;nbsp;Michael Kaplan doesn't flame me for that oversimplification.)&lt;/P&gt;
&lt;P&gt;The NeutralResourcesLanguageAttribute&amp;nbsp;does two things:&lt;/P&gt;
&lt;P&gt;1. Can speed up resource probes. &lt;/P&gt;
&lt;P&gt;First note that the default location for neutral resources is the main assembly. In other words:&lt;BR&gt;[assembly:NeutralResourcesLanguageAttribute("en-US")]&lt;BR&gt;...is the same as:&lt;BR&gt;[assembly:NeutralResourcesLanguageAttribute("en-US", UltimateResourceFallbackLocation.MainAssembly)]&lt;/P&gt;
&lt;P&gt;If you have one of the above attributes on your assembly, then&amp;nbsp;the&amp;nbsp;ResourceManager looks for&amp;nbsp;"en-US" resources&amp;nbsp;directly in&amp;nbsp;the main assembly, instead of searching first in an “en-US” folder. Since resource probes can be expensive, this attribute can help improve perf.&lt;/P&gt;
&lt;P&gt;2. Specifies a fallback culture&amp;nbsp;if resource probes fail; i.e.&amp;nbsp;neutral resources are the resources that should always be there. &lt;/P&gt;
&lt;P&gt;Suppose you want to deploy an app on a machine typically set to de-DE culture. Suppose you have partially localized strings for de-DE and de, and a full set of resources for fr-FR. You can use NeutralResourcesLanguageAttribute to say fr-FR resources are always there. So if the resource probe doesn't find an entry for de-DE or de, then it will fallback to fr-FR. &lt;/P&gt;
&lt;P&gt;You can use the accompanying attribute UltimateResourceFallbackLocation.Satellite to say these resources are located in a satellite assembly, i.e.:&lt;BR&gt;[assembly:NeutralResourcesLanguageAttribute("fr-FR", UltimateResourceFallbackLocation.MainAssembly)]&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9061001" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author><category term="resources" scheme="http://blogs.msdn.com/kimhamil/archive/tags/resources/default.aspx" /></entry><entry><title>Making a StreamWriter usable even after given garbage characters</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2008/11/11/making-a-streamwriter-usable-even-after-given-garbage-characters.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2008/11/11/making-a-streamwriter-usable-even-after-given-garbage-characters.aspx</id><published>2008-11-11T14:10:00Z</published><updated>2008-11-11T14:10:00Z</updated><content type="html">&lt;P&gt;I recently got a question from a customer using a StreamWriter with a UTF-8 encoding.&amp;nbsp;The StreamWriter&amp;nbsp;threw an EncoderFallbackException on an attempt to write “garbage” Unicode characters. For example, on an attempt to write U+DFC9, which is only half of a Unicode character (not a complete surrogate pair) an EncoderFallbackException was thrown.&lt;/P&gt;
&lt;P&gt;That part seemed fine since the input was bogus. However, after that exception is thrown, the StreamWriter instance became effectively unusable; even calling WriteLine() on it threw EncoderFallbackException. So the customer asked&amp;nbsp;how to make the writer usable even after the exception.&lt;/P&gt;
&lt;P&gt;This behavior seems bad but it isn't a bug that, by default, the&amp;nbsp;StreamWriter becomes unusable after getting bogus data. This was a design decision (from long ago) to make StreamWriter tolerant of encoding errors when reading but very strict when writing. Anything you do subsequently –- Flush(), Close(), etc would hit the encoding error again. The idea is, when you encounter an initial error, you should probably be concerned about fidelity of the rest of the stream, so just bail out as soon as you detect the stream is corrupt.&lt;/P&gt;
&lt;P&gt;In this case, the customer was fine with not attempting to write garbage characters, but didn't want to StreamWriter to become unusable; for example to avoid losing the previous data. &lt;/P&gt;
&lt;P&gt;Fortunately there's a solution since the&amp;nbsp;encoding's EncoderFallback property can be set&amp;nbsp;to emit fallback characters instead of throwing an exception.&amp;nbsp;In this example, the encoding's&amp;nbsp;default&amp;nbsp;fallback behavior was to throw an exception; however, you can set the property to use a replacement character, e.g.: Encoding.EncoderFallback = EncoderFallback.ReplacementFallback. Then,&amp;nbsp;instead of getting an EncoderFallbackException, the bogus characters&amp;nbsp;are replaced with the fallback, and the StreamWriter continues to be usable.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9060037" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author><category term="IO" scheme="http://blogs.msdn.com/kimhamil/archive/tags/IO/default.aspx" /></entry><entry><title>When to call Dispose</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2008/11/05/when-to-call-dispose.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2008/11/05/when-to-call-dispose.aspx</id><published>2008-11-06T09:26:00Z</published><updated>2008-11-06T09:26:00Z</updated><content type="html">&lt;P&gt;A recent internal email thread unearthed extreme differences of opinion about when Dispose(void) should be called on an IDisposable. This led to a long discussion and a realization that -- while it seems like we’ve said everything there is to say about Dispose -- it’s time for some more Dispose guidance. This blog summarizes our initial thoughts about when you should call Dispose. Input was provided by Jeffrey Richter, Mike Boilen, Brian Grunkemeyer, Joe Duffy, and Shawn Farkas. We'd like to hear your feedback as well.&lt;/P&gt;
&lt;P&gt;Before diving in, some context:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The question of when to call Dispose is just a small piece of the Dispose puzzle. For information about correctly implementing the Dispose pattern, see the updated &lt;A href="http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae" mce_href="http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae"&gt;Dispose guidelines&lt;/A&gt; on Joe Duffy’s blog.&lt;/LI&gt;
&lt;LI&gt;As a quick refresher, calling Dispose(void) releases resources deterministically (as opposed to nondeterministic cleanup at finalization).&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;B&gt;The Debate&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Let’s look at the different opinions.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;“Always call Dispose” camp&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;The people in this camp, which included me, have been burned by cases in which failing to call Dispose can lead to bugs. For example, failure to call Dispose on a FileStream can lead to hard-to-spot bugs where the file is temporarily unavailable. Even worse, failure to explicitly dispose some .NET crypto classes can lead to an exception thrown on the finalizer thread. Based on these and other examples, we concluded the pit of success is to always call Dispose.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;“Avoid calling Dispose” camp&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;Jeffrey Richter was the lone voice in this camp, but he was up to the challenge. He pointed out that many IDisposables are not as clear cut as FileStream, Socket, etc. For example, a Winforms app has IDisposables that are fonts, controls, etc. For these, explicit cleanup isn’t necessary in mainstream scenarios. Calling Dispose on each of these would be incredibly tedious – similar to (but not as bad as) C++ destructor style of cleanup. &lt;/P&gt;
&lt;P&gt;Jeffrey also provided an example where Dispose shouldn't be called. The IAsyncResults returned by FileStream.BeginRead and BeginWrite have a WaitHandle member, which implements IDisposable. Jeffrey said some users think that they should aggressively fetch and dispose this WaitHandle. This can obviously have bad consequences if done prematurely, but it has another problem. The WaitHandle is lazily allocated, so fetching it just to dispose it causes an unnecessary allocation (i.e. negatively impacts performance).&lt;/P&gt;
&lt;P&gt;He pointed out similar APIs where there is confusion over whether to call Dispose; in general, these are APIs in where there is ambiguity about who owns the IDisposable.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Who won?&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Well, everyone...or no one. (Actually, probably Jeffrey, given that I didn't think he could budge my opinion at all.)&lt;/P&gt;
&lt;P&gt;In any case, from our discussion, it was obvious we haven’t enunciated clear guidance about when to call Dispose. &lt;/P&gt;
&lt;P&gt;Given the already confusing state of Dispose, we’d like to keep this guidance as simple as possible. Previously (before that email thread), I thought we wanted to tell users to always call Dispose, since doing so prevents bad side effects described above. The IAsyncResult / unnecessary allocation example could be solved by telling users not to aggressively fetch and dispose members. (In fact, this needs to be advertised no matter what.) This guidance is very simple. So why complicate things?&lt;/P&gt;
&lt;P&gt;Jeffrey’s point about the impact of this guidance on WinForms-like apps is crucial. Having to call Dispose on each font and control in a WinForms app could significantly impact coding patterns and would be viewed as tedious. It’s not _as_ tedious as C++ destructors (since at least managed memory is handled), but it’s still a lot of bookkeeping that would be nice to avoid, as long as it's safe.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Proposed guidance about when to call Dispose (draft)&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;The simplest story we found combining these two concerns (correctness and usability) was to divide IDisposables into resource categories and give specific guidance for each category. The key observation, provided by Mike Boilen, is that you should call Dispose when failing to do so can lead to visible side effects. This approach covers most of our Dispose concerns; special cases are listed in the next section.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Resource Categories&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;1. Named/shared OS resources&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Examples: files, sockets, named pipes, memory mapped files&lt;/LI&gt;
&lt;LI&gt;Failure to call Dispose: likely to have visible side effects. Even if the resource is wrapped with a SafeHandle or class has a finalizer, problems can manifest as the resource being unavailable for some period of time&lt;/LI&gt;
&lt;LI&gt;When to call Dispose: if you own it, Dispose it&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;2. Other/unnamed resources&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Examples: native fonts, controls, bitmaps (native memory)&lt;/LI&gt;
&lt;LI&gt;Failure to call Dispose: only has visible side effects when large amounts are used. These resources have higher limits than resource category 1. In “typical” use, limits are not hit*&lt;/LI&gt;
&lt;LI&gt;When to call Dispose: only if limit is likely to be hit. Rely on GC cleanup for typical use&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;To keep this simple for users, we could flag in the docs the classes that you must call Dispose on (i.e. resource category 1). Guidance for resource category 2 is left vague at the moment; the intent for now is to get feedback about whether this approach addresses usability concerns, while remaining as simple as possible.&lt;/P&gt;
&lt;P&gt;*Scenarios that expect to stress the resource may hit limits and should consider calling Dispose.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Other Dispose-related special cases&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Unfortunately we have to complicate the story. These will also have to be handled on a case-by-case basis.&lt;/P&gt;
&lt;P&gt;1. Classes with very different lifetimes: We’d like to recommend not holding strong references to objects that have shorter lifetime&lt;/P&gt;
&lt;P&gt;2. Impersonation-related problems: Dispose must be called for crypto classes in which finalizer thread runs under different identity and process is ripped. &lt;/P&gt;
&lt;P&gt;3. Bad/degenerate cases: if we suggest not to call Dispose for resource category 2, and a class using one of those resources has not handled cleanup via safehandles or finalizers, then we’re causing a new problem. Do we even care about this? &lt;/P&gt;
&lt;P&gt;4. Ambiguous resource type: for some APIs that return an IDisposable, it’s not obvious what kind of resource is wrapped. If failure to call Dispose for any of the resources may lead to observable side effects, the docs must call this out.&lt;/P&gt;
&lt;P&gt;5. Ambiguous ownership: for some APIs that return an IDisposable, it’s not clear whether the method allocated the IDisposable and you own the single reference, or you’re referencing a shared instance. Ownership ambiguity will require clarification in docs. In any case, you shouldn’t fetch IDisposable members and dispose them, as in the IAsyncResult case.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;What’s next?&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Whatever distinction we eventually use, API docs should explicitly call out IDisposables that must be Disposed.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Any comments?&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9047192" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author><category term="Dispose" scheme="http://blogs.msdn.com/kimhamil/archive/tags/Dispose/default.aspx" /></entry><entry><title>FileSystemWatcher doesn't fire events for monitored network drive after changing InternalBufferSize</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2008/04/27/filesystemwatcher-doesn-t-fire-events-for-monitored-network-drive-after-changing-internalbuffersize.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2008/04/27/filesystemwatcher-doesn-t-fire-events-for-monitored-network-drive-after-changing-internalbuffersize.aspx</id><published>2008-04-28T02:07:00Z</published><updated>2008-04-28T02:07:00Z</updated><content type="html">&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;&lt;/H2&gt;
&lt;H5&gt;Problem and .NET Fix&lt;/H5&gt;
&lt;P&gt;Some customers have observed that a FileSystemWatcher monitoring a network drive fails to fire events after setting InternalBufferSize to certain values. The problem is that the value provided to InternalBufferSize is invalid and FileSystemWatcher attempts to notify your error handler when you enable raising events, but without an error handler you won't know about the problem. &lt;/P&gt;
&lt;P&gt;The sample code below demonstrates this problem. If you uncomment the line that adds an error handler, then you'll get notification. Note that this is one of the many reasons it's important to add an error handler. &lt;/P&gt;
&lt;P&gt;Unfortunately this particular failure is a bit more complicated than adding an error handler. In current releases, FileSystemWatcher has a bug in which it returns the wrong error if you request an invalid buffer size. Even if you add an error handler, ErrorEventArgs.GetException() will show this exception:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=cou&gt;System.ComponentModel.Win32Exception: The operation completed successfully&lt;/FONT&gt; &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;But this is what you should see: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=cou&gt;System.ComponentModel.Win32Exception: The supplied user buffer is not valid for the requested operation&lt;/FONT&gt; &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;We've already fixed this bug and the fix will appear in the next major runtime release. To clarify, with the fixed version, you will still get the exception in the error handler, but the exception message will be correct. &lt;/P&gt;
&lt;H5&gt;Workaround&lt;/H5&gt;
&lt;P&gt;With and without the runtime bug, setting the InternalBufferSize to 25 * 4096 is failing. To find a good buffer size, you can use the fact that, if your buffer size is valid, then it won't result in your error handler being called (i.e. it won't really get called to tell you the operation was successful). So you can experiment with buffer size; for example this succeeds for me:&lt;/P&gt;
&lt;P&gt;watcher.InternalBufferSize = 4 * 4096; &lt;/P&gt;
&lt;P&gt;You can try this out using the sample code below.&lt;/P&gt;
&lt;H5&gt;Sample Code&lt;/H5&gt;
&lt;P&gt;&lt;FONT face=couri&gt;using System; &lt;BR&gt;using System.IO; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;class Repro &lt;BR&gt;&lt;/FONT&gt;&lt;FONT face=couri&gt;{ &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void Main() &lt;BR&gt;&lt;/FONT&gt;&lt;FONT face=couri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // string networkDir = ???; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileSystemWatcher watcher = new FileSystemWatcher(networkDir, "*.*"); &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; watcher.Created += OnCreated; &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // uncomment out line below to add the error handler&lt;/FONT&gt;&lt;FONT face=couri&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // watcher.Error += OnError; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; watcher.IncludeSubdirectories = true; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; watcher.InternalBufferSize = 25 * 4096; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // watcher.InternalBufferSize = 4 * 4096; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; watcher.NotifyFilter = NotifyFilters.FileName; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; watcher.EnableRaisingEvents = true; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (Console.ReadLine() != "x") { } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; watcher.Dispose(); &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static void OnCreated(object source, FileSystemEventArgs e) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static void OnError(object source, ErrorEventArgs e) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Error!"); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(e.GetException()); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=couri&gt;} &lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8433207" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author><category term="IO" scheme="http://blogs.msdn.com/kimhamil/archive/tags/IO/default.aspx" /></entry><entry><title>VisualStudio 2008 install failing because of pre-release products</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2008/03/26/visualstudio-2008-install-failing-because-of-pre-release-products.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2008/03/26/visualstudio-2008-install-failing-because-of-pre-release-products.aspx</id><published>2008-03-26T22:14:54Z</published><updated>2008-03-26T22:14:54Z</updated><content type="html">&lt;p&gt;&lt;/p&gt;  &lt;p&gt;I can get my work machines into pretty odd states due to various private/beta versions of Microsoft products I've installed. While trying to install VS 2008 on one of my machines, install kept failing, saying I had a pre-release product installed. Problem was, I'd already uninstalled that product and it didn't show up in Add/Remove programs. Varun Gupta's blog posts led me through fixing this problem, so I wanted to show that process in case anyone else is running into thsi issue.&lt;/p&gt;  &lt;p&gt;Let's start from the beginning.&lt;/p&gt;  &lt;p&gt;The first time I tried to install VisualStudio 2008, I got the following error dialog, saying that a pre-release of Microsoft Document Explorer was installed.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/kimhamil/WindowsLiveWriter/VisualStudio2008installfailingbecauseofp_AC34/clip_image002%5B5%5D.jpg"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="134" alt="clip_image002[5]" src="http://blogs.msdn.com/blogfiles/kimhamil/WindowsLiveWriter/VisualStudio2008installfailingbecauseofp_AC34/clip_image002%5B5%5D_thumb.jpg" width="244" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;That dialog links to &lt;a href="http://www.microsoft.com/express/support/uninstall/"&gt;http://www.microsoft.com/express/support/uninstall/&lt;/a&gt;, which describes every product that should be uninstalled. This list included Document Explorer. To be safe, I uninstalled every program in the list.&lt;/p&gt;  &lt;p&gt;Then I launched the VisualStudio 2008 setup again, but got the same error dialog, saying that a pre-release version of Microsoft Document Explorer was installed. Microsoft Document Explorer no longer appeared in Add/Remove programs, so it was time for some Live searches. :)&lt;/p&gt;  &lt;p&gt;I landed on &lt;a href="http://blogs.msdn.com/varungupta/archive/2007/12/04/visual-studio-2008-setup-troubleshooting-guide.aspx" target="_blank"&gt;Varun Gupta's VS 2008 Troubleshooting Guide.&lt;/a&gt; Note that section 1,B,3,b,ii in his guide applies to this case. Following his instructions there, I ran msiinv.exe to get the list of installed components. In the output file, there was this entry:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier"&gt;Microsoft Document Explorer 2005       &lt;br /&gt;Product code: {0913C927-03D9-3FE1-B8A4-7A4C0C435A4F}        &lt;br /&gt;Product state: (5) Installed.        &lt;br /&gt;...&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Varun's next step says to use msiexec /x to remove the product:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier" size="2"&gt;msiexec /x {0913C927-03D9-3FE1-B8A4-7A4C0C435A4F}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I re-launched VS 2008 setup, and it worked! Thanks Varun for posting these useful instructions. Now I can get back to work. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8338301" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author></entry><entry><title>Difference between Disposing and Finalizing (referral)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2008/03/23/difference-between-disposing-and-finalizing-referral.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2008/03/23/difference-between-disposing-and-finalizing-referral.aspx</id><published>2008-03-23T22:49:00Z</published><updated>2008-03-23T22:49:00Z</updated><content type="html">&lt;P&gt;I've gotten some pings on the difference between Disposing and Finalizing, which I didn't discuss in&amp;nbsp;my Dispose/Close post. Fortunately Brian Grunkemeyer has written an excellent blog on the topic:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/bclteam/archive/2007/10/30/dispose-pattern-and-object-lifetime-brian-grunkemeyer.aspx"&gt;http://blogs.msdn.com/bclteam/archive/2007/10/30/dispose-pattern-and-object-lifetime-brian-grunkemeyer.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8332556" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author><category term="Dispose" scheme="http://blogs.msdn.com/kimhamil/archive/tags/Dispose/default.aspx" /></entry><entry><title>The never-ending saga of Close/Dispose</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2008/03/17/the-never-ending-saga-of-close-dispose.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2008/03/17/the-never-ending-saga-of-close-dispose.aspx</id><published>2008-03-17T21:23:00Z</published><updated>2008-03-17T21:23:00Z</updated><content type="html">&lt;P&gt;I made some quick updates in my recent post to describe the difference between Close and Dispose for SqlConnection:&lt;BR&gt;&lt;A href="http://blogs.msdn.com/kimhamil/archive/2008/03/15/the-often-non-difference-between-close-and-dispose.aspx" mce_href="http://blogs.msdn.com/kimhamil/archive/2008/03/15/the-often-non-difference-between-close-and-dispose.aspx"&gt;http://blogs.msdn.com/kimhamil/archive/2008/03/15/the-often-non-difference-between-close-and-dispose.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;If you're wondering about the difference between Close and Dispose for classes I didn't mention, feel free to comment. I'm curious to unearth any other occurrences.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8293481" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author><category term="IO" scheme="http://blogs.msdn.com/kimhamil/archive/tags/IO/default.aspx" /><category term="Dispose" scheme="http://blogs.msdn.com/kimhamil/archive/tags/Dispose/default.aspx" /></entry><entry><title>The (often non-) difference between Close and Dispose</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2008/03/15/the-often-non-difference-between-close-and-dispose.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2008/03/15/the-often-non-difference-between-close-and-dispose.aspx</id><published>2008-03-16T04:43:00Z</published><updated>2008-03-16T04:43:00Z</updated><content type="html">&lt;P&gt;Some classes in the .NET framework, such as System.IO.FileStream, have both a Close() and Dispose() method. The natural question is what's the difference, and when you should use one versus the other. &lt;/P&gt;
&lt;P&gt;The &lt;A href="http://msdn2.microsoft.com/en-us/library/b1yfkh5e.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/b1yfkh5e.aspx"&gt;framework guidelines&lt;/A&gt; refer to Close and Dispose in the following context: occasionally you may prefer to use a domain-specific word instead of Dispose; for example, for files you may prefer to expose a method called Close(), because this word may be easier for users to discover. But even in that case, Close should just call Dispose.&lt;/P&gt;
&lt;P&gt;That's pretty straightforward, but confusion abounds. A few months ago, while investigating a bug innocently titled "ResourceReader doesn't provide a Dispose method", I realized the cause of the confusion: understanding the variations of Dispose and Close throughout the framework, as well as the guidance going forward, requires a surprising amount of background. If you're confused by conflicting (or seemingly conflicting) information about Close/Dispose in forums, etc, I hope this will help make sense of it all.&lt;/P&gt;
&lt;H5&gt;What is the difference between Close and Dispose?&lt;/H5&gt;
&lt;P&gt;In most .NET framework classes, there is no difference between Close() and Dispose(). For example, these methods do the same thing in the System.IO.Stream hierarchy, and it doesn't matter which of the two methods you call. You should call one but not both.&lt;/P&gt;
&lt;P&gt;There are exceptions; for example, System.Windows.Forms.Form and System.Data.SqlClient.SqlConnection have different behavior for Close() and Dispose(). &lt;/P&gt;
&lt;P&gt;But if you're looking for a rule of thumb, it's best if you think of Close() and Dispose() as the same in general, and others as special cases. We'll discuss these exceptions later.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Terminology note: I've been referring to Dispose() to distinguish it from Dispose(bool). Subsequently, when I use "Dispose" I mean Dispose(). &lt;/EM&gt;&lt;/P&gt;
&lt;H5&gt;&lt;/H5&gt;
&lt;H5&gt;But Close sounds less invasive than Dispose...? &lt;/H5&gt;
&lt;P&gt;This is a common perception about the difference between Close and Dispose, and it's a reasonable guess. We &lt;EM&gt;could&lt;/EM&gt; have set the expectation up front that Dispose is always the name of the method that performs deterministic cleanup. Classes could have added a Close method to do something domain-specific without necessarily implying disposal. But as it stands, they generally do the same thing.&lt;/P&gt;
&lt;H5&gt;But why would they do the same thing?&lt;/H5&gt;
&lt;P&gt;This is where it gets weird. Before Whidbey, many classes used this guidance: if there's a domain-specific word that's more discoverable to users than Dispose, hide Dispose by explicitly implementing it, and instead expose the domain-specific word. &lt;EM&gt;This guidance was primarily intended for file-related classes, and the domain-specific word in that case is Close&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;Any class that hid Dispose and instead exposed Close established that Close and Dispose were equivalent for that class (and its subclasses). Note that it's not obvious that Close and Dispose should do the same thing in general. For Sockets, some users initially guess that Close just closes the Socket (but you can reopen). But Socket.Close does the same thing as Dispose. (FYI, Socket.Disconnect is the method that makes it reopenable.)&lt;/P&gt;
&lt;P&gt;Around Whidbey, it was realized that the rules around Dispose needed to be tightened up. C++ destructors -- which are deterministic -- needed to map to Dispose (the general Framework solution for deterministic cleanup). This motivated some investigation in which we realized some practices&amp;nbsp;made it easy for classes to break disposal chains in a class hierarchy: these included hiding Dispose() and making Dispose() virtual. &lt;/P&gt;
&lt;P&gt;To help prevent this problem, many framework classes (such as the Stream hierarchy) were cleaned up to ensure Dispose() was public and non-virtual, and the subclasses were properly chained via Dispose(bool).&lt;/P&gt;
&lt;P&gt;There are still classes such as ResourceReader in which Dispose is hidden. This is because&amp;nbsp;sealed classes were considered lower priority; the interesting problems happen for class hierarchies, in which Dispose(bool) needs to be chained.&lt;/P&gt;
&lt;P&gt;Even after this cleanup, there&amp;nbsp;remain at least 2 classes in which Close and Dispose are different. This is because these classes weren't hiding Dispose for Close: Close and Dispose really did something different for these classes.&lt;/P&gt;
&lt;H5&gt;Hiding Dispose, explicit implementation...what does that mean?&lt;/H5&gt;
&lt;P&gt;Hiding Dispose through explicit interface implementation means doing this: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;void &lt;STRONG&gt;IDisposable.Dispose&lt;/STRONG&gt;() &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dispose(true); &lt;BR&gt;}&lt;/FONT&gt; &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;...as opposed to this: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;public void Dispose() &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dispose(true); &lt;BR&gt;}&lt;/FONT&gt; &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Let's look at the consequences of using a class that's explicitly implements Dispose. ResourceReader explicitly implements Dispose, so let's use that as an example.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;ResourceReader rr = new ResourceReader(resourceStream); &lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&lt;FONT face=Arial&gt;The following yields a compile error: 'System.Resources.ResourceReader' does not contain a definition for 'Dispose'&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;rr.Dispose();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Casting to IDisposable lets you call Dispose:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;((IDisposable)rr).Dispose();&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Since Close and Dispose do the same thing, the above is equivalent to:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;rr.Close();&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H5&gt;&lt;/H5&gt;
&lt;H5&gt;Unfortunate side-effects of hiding Dispose&lt;/H5&gt;
&lt;P&gt;The guidance about hiding Dispose got applied in interesting ways. For example, in some crypto classes, Dispose is hidden and the domain-specific word for disposal is Clear. Shawn Farkas pointed out that this has caused problems: some people don't recognize Clear as a disposal method, and they don't even know they're supposed to dispose the object.&lt;/P&gt;
&lt;P&gt;Hiding Dispose causes confusion for many users, who think of Dispose as the go-to method for disposal. From that perspective, hiding Dispose in favor of the domain-specific word can actually make the disposal method less discoverable. The need to cast it to IDisposable is unintuitive to many users.&lt;/P&gt;
&lt;H5&gt;What about the classes where Close and Dispose are different?&lt;/H5&gt;
&lt;P&gt;In my search, I only confirmed that 2 classes have different behavior for Close and Dispose: System.Windows.Forms.Form and System.Data.SqlClient.SqlConnection. There could be more because more because my search wasn't exhaustive; I identified likely candidates and only looked into those.&lt;/P&gt;
&lt;P&gt;Let's look at System.Windows.Forms.Form. Here are some interesting excerpts from the docs for Form.Close:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" size=2&gt;When a form is closed, all resources created within the object are closed and the form is disposed.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" size=2&gt;…&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Lucida Sans Unicode" size=2&gt;The one condition when a form is not disposed on &lt;B&gt;Close&lt;/B&gt; is when it is part of a multiple-document interface (MDI) application, and the form is not visible. In this case, you will need to call &lt;/FONT&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/d305e9bx(VS.80).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/d305e9bx(VS.80).aspx"&gt;&lt;FONT face="Lucida Sans Unicode" size=2&gt;Dispose&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face="Lucida Sans Unicode" size=2&gt; manually to mark all of the form's controls for garbage collection.&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The second part seems to indicate they're different, but it's a bit buried in the description. Let's open it in reflector to be sure.&lt;/P&gt;&lt;PRE&gt;public &lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Void" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Void"&gt;void&lt;/A&gt; &lt;B&gt;&lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.Form/Close()" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.Form/Close()"&gt;Close&lt;/A&gt;&lt;/B&gt;()
{
    if (base.&lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.Control/GetState(Int32):Boolean" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.Control/GetState(Int32):Boolean"&gt;GetState&lt;/A&gt;(0x40000))
    {
        throw new &lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.InvalidOperationException/.ctor(String)" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.InvalidOperationException/.ctor(String)"&gt;InvalidOperationException&lt;/A&gt;(&lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.SR" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.SR"&gt;SR&lt;/A&gt;.&lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.SR/GetString(String,Object%5b%5d):String" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.SR/GetString(String,Object%5b%5d):String"&gt;GetString&lt;/A&gt;("ClosingWhileCreatingHandle", new &lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Object" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Object"&gt;object&lt;/A&gt;[] { "Close" }));
    }
&lt;STRONG&gt;&lt;FONT color=#008000&gt;    if (base.&lt;/FONT&gt;&lt;/STRONG&gt;&lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.Control/property:IsHandleCreated:Boolean" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.Control/property:IsHandleCreated:Boolean"&gt;&lt;STRONG&gt;&lt;FONT color=#008000&gt;IsHandleCreated&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt;&lt;FONT color=#008000&gt;)&lt;/FONT&gt;&lt;/STRONG&gt;
    {
        this.&lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.Form/closeReason:System.Windows.Forms.CloseReason" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.Form/closeReason:System.Windows.Forms.CloseReason"&gt;closeReason&lt;/A&gt; = &lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.CloseReason" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.CloseReason"&gt;CloseReason&lt;/A&gt;.&lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.CloseReason/UserClosing" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.CloseReason/UserClosing"&gt;UserClosing&lt;/A&gt;;
        base.&lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.Control/SendMessage(Int32,Int32,Int32):IntPtr" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Windows.Forms:2.0.0.0:b77a5c561934e089/System.Windows.Forms.Control/SendMessage(Int32,Int32,Int32):IntPtr"&gt;SendMessage&lt;/A&gt;(0x10, 0, 0);
    }
    else
    {
        base.&lt;A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System:2.0.0.0:b77a5c561934e089/System.ComponentModel.Component/Dispose()" mce_href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System:2.0.0.0:b77a5c561934e089/System.ComponentModel.Component/Dispose()"&gt;Dispose&lt;/A&gt;();
    }
}&lt;/PRE&gt;
&lt;P&gt;So indeed, it&amp;nbsp;won't go down the Dispose path if base.IsHandleCreated is true. &lt;/P&gt;
&lt;P&gt;For System.Data.SqlClient.SqlConnection, the primary difference between Close and Dispose is that&amp;nbsp;Dispose nulls out _userConnectionOptions and _poolGroup, as shown below. While I'm not familar with the code in System.Data.dll, by browsing around in reflector it looks like this has the effect of making the SqlConnection object unusable; i.e. it throws if you try to re-open. Anyone familiar with this class can feel free to chime in if there's a better way to describe this. :)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#1000a0&gt;this&lt;/FONT&gt;.&lt;A title="DbConnectionOptions System.Data.SqlClient.SqlConnection._userConnectionOptions;" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Data:2.0.0.0:b77a5c561934e089/System.Data.SqlClient.SqlConnection/_userConnectionOptions:System.Data.Common.DbConnectionOptions"&gt;&lt;FONT color=#006018&gt;_userConnectionOptions&lt;/FONT&gt;&lt;/A&gt; = &lt;FONT color=#800000&gt;null&lt;/FONT&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#1000a0&gt;this&lt;/FONT&gt;.&lt;A title="DbConnectionPoolGroup System.Data.SqlClient.SqlConnection._poolGroup;" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Data:2.0.0.0:b77a5c561934e089/System.Data.SqlClient.SqlConnection/_poolGroup:System.Data.ProviderBase.DbConnectionPoolGroup"&gt;&lt;FONT color=#006018&gt;_poolGroup&lt;/FONT&gt;&lt;/A&gt; = &lt;FONT color=#800000&gt;null&lt;/FONT&gt;;&lt;BR&gt;&lt;/P&gt;
&lt;H5&gt;Guidance now&lt;/H5&gt;
&lt;P&gt;Joe Duffy's blog has the complete updated Dispose Design Guidelines. This is great reading for detailed guidance around Dispose and finalization (including when they should be used, implications for class hierarchies, etc):&lt;/P&gt;
&lt;P&gt;&lt;A title=http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae href="http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae" mce_href="http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae"&gt;http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Based on this experience, I'd encourage you to think very carefully before attempting to use a domain-specific name instead of Dispose -- we're now at a place where users are familiar with Dispose and it &lt;EM&gt;is&lt;/EM&gt; the most discoverable method name.&lt;/P&gt;
&lt;P&gt;I think we should also impose some order by making it very clear in our docs when Close and Dispose are the same, and clearly call out any cases that differ.&lt;/P&gt;
&lt;P&gt;Thanks to Krzysztof Cwalina, Joe Duffy, and Brian Grunkemeyer, who provided valuable input to my barrage of emails on this topic. :)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8237816" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author><category term="IO" scheme="http://blogs.msdn.com/kimhamil/archive/tags/IO/default.aspx" /><category term="Dispose" scheme="http://blogs.msdn.com/kimhamil/archive/tags/Dispose/default.aspx" /></entry><entry><title>What's been happening with Long Paths?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2008/03/08/what-s-been-happening-with-long-paths.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2008/03/08/what-s-been-happening-with-long-paths.aspx</id><published>2008-03-09T04:46:00Z</published><updated>2008-03-09T04:46:00Z</updated><content type="html">&lt;P&gt;It appears that part 3 of the &lt;A href="http://blogs.msdn.com/bclteam/archive/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton.aspx" mce_href="http://blogs.msdn.com/bclteam/archive/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton.aspx"&gt;long path blog series&lt;/A&gt; on the BCL blog is now nearly a year overdue! This sounds hard to believe, but BCL really has been &lt;EM&gt;that busy&lt;/EM&gt;. On the bright side, we've been working on exciting projects, such as &lt;A href="http://silverlight.net/" mce_href="http://silverlight.net/"&gt;Silverlight&lt;/A&gt;, and now that we're coming up for air, we should have tons more stuff to blog about.&lt;/P&gt;
&lt;P&gt;No more excuses. I know a year is way too long to wait for the conclusion of a series. Well, unless it's Lord of the Rings. So I've been getting back to long paths top priority, and part 3 will be out this week.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8115712" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author><category term="IO" scheme="http://blogs.msdn.com/kimhamil/archive/tags/IO/default.aspx" /><category term="Long paths" scheme="http://blogs.msdn.com/kimhamil/archive/tags/Long+paths/default.aspx" /></entry><entry><title>Hashtable and Dictionary thread safety considerations</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kimhamil/archive/2008/03/08/hashtable-and-dictionary-thread-safety-considerations.aspx" /><id>http://blogs.msdn.com/kimhamil/archive/2008/03/08/hashtable-and-dictionary-thread-safety-considerations.aspx</id><published>2008-03-08T12:42:00Z</published><updated>2008-03-08T12:42:00Z</updated><content type="html">&lt;P&gt;Let’s start with the basics: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;System.Collections.Hashtable is multiple-reader, single-writer threadsafe. &lt;/LI&gt;
&lt;LI&gt;System.Collections.Generic.Dictionary&amp;lt;K,V&amp;gt; has no thread safety guarantees. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Consider a class that has a Dictionary member, and assume that multiple threads may access it simultaneously. Taking a lock is expensive, so what do you think about the following attempt to defer taking a lock?&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Courier&gt;&lt;/FONT&gt;&lt;/P&gt;class ElementManager { &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Dictionary&amp;lt;String, Element&amp;gt; cache = &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; new Dictionary&amp;lt;String, Element&amp;gt;(); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Object o = new Object(); &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Not to ruin the punchline, but I don't want someone to copy &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // and paste this flawed code... &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // &lt;B&gt;WARNING: BAD CODE! DON’T USE!&lt;/B&gt; &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Element GetElement(String name) { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Element theElement; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool result = cache.TryGetValue(name, out theElement); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!result) { &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; lock (o) { &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; result = cache.TryGetValue(name, out theElement); &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; if (!result) { &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; theElement = new Element(); &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; cache.Add(name, theElement); &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; } &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; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return theElement; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;} 
&lt;P&gt;GetElement only takes the lock if TryGetValue found no result. So from a performance perspective, it’s a nice try. But it’s not correct: the value returned may not actually correspond to the name. (That’s not just because value may be stale data; value may have never corresponded to name).&lt;/P&gt;
&lt;P&gt;The problem occurs if a reader thread outside of the locked region gets an element while a writer thread adds an element and causes a resize in the Dictionary to occur. If the timing is just right (actually, just wrong) then the reader thread may index incorrectly into the Dictionary (internal implementation details) and return the wrong element.&lt;/P&gt;
&lt;P&gt;This thread-safety difference is a little-known twist in our guidance to convert to using generic collections. If you’re converting from Hashtable to generic Dictionary, you’ll want to consider whether you may have taken a dependency on Hashtable’s MR-SW thread safety without knowing it. (This isn’t very common, but it has happened)&lt;/P&gt;
&lt;P&gt;IMO, better concurrency support is one of the most compelling feature requests for the collections space. This is important for both performance and usability. &lt;/P&gt;
&lt;P&gt;The usability argument may not be obvious, so here’s some background. Our non-generic collections provided synchronized wrappers, which inserted a lock around operations for thread safety. Synchronized wrappers weren’t included with the generic collections, with the argument that one often needs to synchronize at a higher level, over multiple operations (e.g. check if a stack is non-empty and then pop). However, we didn’t provide alternate framework solutions, meaning that users have to implement their own locking for generic collections. This is unnecessarily tedious in the common scenario when you &lt;I&gt;don’t&lt;/I&gt; need to synchronize over multiple operations.&lt;/P&gt;
&lt;P&gt;This doesn’t mean we should add back the synchronized wrappers; there are options with much better performance, but more on that later.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8111732" width="1" height="1"&gt;</content><author><name>kimhamil</name><uri>http://blogs.msdn.com/members/kimhamil.aspx</uri></author><category term="Collections" scheme="http://blogs.msdn.com/kimhamil/archive/tags/Collections/default.aspx" /></entry></feed>