<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title>Logos Bible Software Code Blog</title>
  <link rel="alternate" type="text/html" href="http://code.logos.com/blog/" />
  
  <updated>2012-05-01T07:28:36-07:00</updated>
  <id>tag:code.logos.com,2011:/blog/12</id>

  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/LogosBibleSoftwareCodeBlog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="logosbiblesoftwarecodeblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title>Run MbUnit v2 tests under .NET 4</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/05/run-mbunit-v2-tests-under-net-4.html" />
    <updated>2012-05-01T07:30:00-07:00</updated>
    <id>http://code.logos.com/blog/blog/2012/05/run-mbunit-v2-tests-under-net-4</id>
    <content type="html">&lt;p&gt;We still use &lt;a href="http://www.mbunit.com/"&gt;MbUnit v2&lt;/a&gt; for some of our assemblies,
primarily because the items mentioned in the &lt;a href="http://blog.bits-in-motion.com/2008/10/announcing-gallio-and-mbunit-v304.html"&gt;migration guide&lt;/a&gt;
still haven't been implemented in MbUnit v3, and we haven't taken the time
to port the tests to NUnit.&lt;/p&gt;

&lt;p&gt;I wanted to compile our code for .NET 4 and still run all the existing tests
against it.&lt;/p&gt;

&lt;p&gt;The test runner (&lt;code&gt;MbUnit.Cons.exe&lt;/code&gt;) is a .NET 1.1 app, so by default it will
fail to load a .NET 4 test assembly. You can use the &lt;a href="http://msdn.microsoft.com/en-us/library/w4atty68.aspx"&gt;&lt;code&gt;&amp;lt;supportedRuntime&amp;gt;&lt;/code&gt;&lt;/a&gt; configuration element
to &lt;a href="http://social.msdn.microsoft.com/Forums/en/netfxsetupprerelease/thread/d6d8957e-742a-4cc2-b5c1-d9130ea423d0"&gt;force the program to run under .NET 4&lt;/a&gt;,
but it still fails to load the test assembly.&lt;/p&gt;

&lt;p&gt;The message printed at the console isn't helpful, but if you debug the test
runner, the following exception occurs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NotSupportedException: This method implicitly uses CAS
policy, which has been obsoleted by the .NET Framework.
In order to enable CAS policy for compatibility reasons,
please use the NetFx40_LegacySecurityPolicy configuration
switch.
Please see http://go.microsoft.com/fwlink/?LinkID=155570
for more information.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This occurs because MbUnit uses the obsolete &lt;a href="http://msdn.microsoft.com/en-us/library/0wcskf6d.aspx"&gt;&lt;code&gt;Assembly.Load(string, Evidence)&lt;/code&gt;&lt;/a&gt;
method. To fix this, add the &lt;code&gt;NetFx40_LegacySecurityPolicy&lt;/code&gt; configuration
element, as instructed by the exception message.&lt;/p&gt;

&lt;p&gt;Ultimately, your MbUnit.Cons.exe.config file should look as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;runtime&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Don&amp;#39;t kill application on first uncaught exception. --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;legacyUnhandledExceptionPolicy&lt;/span&gt; &lt;span class="na"&gt;enabled=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Use legacy CAS policy so MbUnit&amp;#39;s assembly loading succeeds. --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;NetFx40_LegacySecurityPolicy&lt;/span&gt; &lt;span class="na"&gt;enabled=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/runtime&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Force use of .NET 4. --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;startup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;supportedRuntime&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;v4.0&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/startup&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;With this new configuration, MbUnit can successfully run under .NET 4 and
load .NET 4 assemblies. However, it still runs as a 32-bit process, so
"Any CPU" test assemblies will get loaded as 32-bit. To make it run as 64-bit,
you can use the &lt;a href="http://msdn.microsoft.com/en-us/library/ms164699.aspx"&gt;CorFlags&lt;/a&gt;
utility. As per the &lt;a href="http://stackoverflow.com/tags/corflags/info"&gt;StackOverflow wiki&lt;/a&gt;,
an "Any CPU" application should be a PE32 executable with the 32BIT flag cleared.&lt;/p&gt;

&lt;p&gt;To change MbUnit to an "Any CPU" executable (so it runs as 64-bit on an
x64 system), run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CorFlags /UpgradeCLRHeader /32BIT- MbUnit.Cons.exe
&lt;/code&gt;&lt;/pre&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/3ubtYpr8SXg" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Persistent Hash Codes</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/02/persistent-hash-codes.html" />
    <updated>2012-02-23T06:32:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/02/persistent-hash-codes</id>
    <content type="html">&lt;p&gt;What does &lt;code&gt;"hello".GetHashCode()&lt;/code&gt; return?&lt;/p&gt;

&lt;p&gt;The answer is: it depends.&lt;/p&gt;

&lt;p&gt;Under the Microsoft .NET 4 CLR, that method returns &lt;code&gt;0xFFF561E1&lt;/code&gt; in a 32-bit application,
but &lt;code&gt;0xEC7BF82A&lt;/code&gt; in a 64-bit build. Other runtimes, such as Mono and the Compact Framework,
might return other values.&lt;/p&gt;

&lt;p&gt;As per &lt;a href="http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx"&gt;the documentation&lt;/a&gt;,
&amp;ldquo;The behavior of GetHashCode is dependent on its implementation, which might change from one version of the common language runtime to another. &amp;hellip; The value returned by GetHashCode is platform-dependent. It differs on the 32-bit and 64-bit versions of the .NET Framework.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;In certain scenarios (e.g., saving a hash code to a file, or creating a hash code on a 32-bit
client and using it on a 64-bit server), it's useful to have an algorithm that will always
generate the same hash code for the same input.&lt;/p&gt;

&lt;p&gt;Based on Paul Hsieh&amp;lsquo;s &lt;a href="http://www.azillionmonkeys.com/qed/hash.html"&gt;SuperFastHash&lt;/a&gt;,
Bob Jenkin&amp;lsquo;s &lt;a href="http://www.burtleburtle.net/bob/hash/doobs.html"&gt;hash function&lt;/a&gt;, and
Thomas Wang&amp;lsquo;s &lt;a href="http://www.concentric.net/~Ttwang/tech/inthash.htm"&gt;Integer Hash Function&lt;/a&gt;,
we developed &lt;code&gt;HashCodeUtility.GetPersistentHashCode&lt;/code&gt;. (The C# methods are basically a straightforward
port of the corresponding C functions.)&lt;/p&gt;

&lt;p&gt;These methods perform a thorough mixing of their input (so the return value works well as a
key in a hashtable), have good performance, and will always return the same result no matter
what version of the CLR they're running on.&lt;/p&gt;

&lt;p&gt;The source is available on GitHub: &lt;a href="https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/HashCodeUtility.cs"&gt;HashCodeUtility.cs&lt;/a&gt;,
&lt;a href="https://github.com/LogosBible/Logos.Utility/blob/master/tests/Logos.Utility.Tests/HashCodeUtilityTests.cs"&gt;HashCodeUtilityTests.cs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For information about the &lt;code&gt;CombineHashCodes&lt;/code&gt; method in those files, see my earlier post,
&lt;a href="http://code.logos.com/blog/2010/02/creating_hash_codes.html"&gt;Creating hash codes&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/oGUUbgZQcqs" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Ascii85 implementation in C#</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/02/ascii85-implementation-in-csharp.html" />
    <updated>2012-02-18T11:25:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/02/ascii85-implementation-in-csharp</id>
    <content type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Ascii85"&gt;Ascii85&lt;/a&gt; is an encoding scheme that converts 4 bytes into 5 ASCII characters (in the range &lt;code&gt;!&lt;/code&gt; through &lt;code&gt;u&lt;/code&gt;). As a result, it only has 25% encoding overhead compared to the 33% of &lt;a href="http://en.wikipedia.org/wiki/Base64"&gt;Base64&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I recently needed to smuggle some binary data through HTTP headers without &lt;a href="http://code.logos.com/blog/2012/01/webexception-the-message-limit-length-was-exceeded.html"&gt;exceeding the message length limit&lt;/a&gt;; Ascii85 seemed like the best choice.&lt;/p&gt;

&lt;p&gt;There were a couple of implementations available on the &lt;a href="http://www.codinghorror.com/blog/2009/05/the-bathroom-wall-of-code.html"&gt;bathroom wall of code&lt;/a&gt;, but they had various problems that precluded their use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No tests&lt;/li&gt;
&lt;li&gt;Few comments&lt;/li&gt;
&lt;li&gt;Unknown license&lt;/li&gt;
&lt;li&gt;Violated .NET Framework Design Guidelines&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Not_invented_here"&gt;NIH&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So I wrote my own. The code is available on GitHub: &lt;a href="https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/Ascii85.cs"&gt;Ascii85.cs&lt;/a&gt;, &lt;a href="https://github.com/LogosBible/Logos.Utility/blob/master/tests/Logos.Utility.Tests/Ascii85Tests.cs"&gt;Ascii85Tests.cs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As with the other code on this blog, it's released under a &lt;a href="http://code.logos.com/blog/2008/09/logos_code_blog_license.html"&gt;MIT-style license&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/XqWgO4ZbDRs" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>WebException: "The message length limit was exceeded"</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/01/webexception-the-message-limit-length-was-exceeded.html" />
    <updated>2012-01-04T13:04:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/01/webexception-the-message-limit-length-was-exceeded</id>
    <content type="html">&lt;p&gt;An uncommon &lt;code&gt;WebException&lt;/code&gt; thrown by &lt;code&gt;HttpWebRequest.GetResponse()&lt;/code&gt; has the message
"The underlying connection was closed: The message length limit was exceeded."&lt;/p&gt;

&lt;p&gt;By default, &lt;code&gt;HttpWebResponse&lt;/code&gt; only allows 64KB of HTTP headers; any more and
it will throw this exception.&lt;/p&gt;

&lt;p&gt;To resolve the issue, set the &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.maximumresponseheaderslength.aspx"&gt;MaximumResponseHeadersLength&lt;/a&gt;
property on the request to a larger value, or to &lt;code&gt;-1&lt;/code&gt; for no limit. (Note that the value is
expressed in kilobytes, so the default value &lt;code&gt;64&lt;/code&gt; allows 65,536 bytes of headers.)&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/Rn9S4wz0Hig" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Avoid System.Windows.Rect.ToString()</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/01/avoid-system-windows-rect-tostring.html" />
    <updated>2012-01-02T12:03:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/01/avoid-system-windows-rect-tostring</id>
    <content type="html">&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms521832.aspx"&gt;System.Windows.Rect.ToString()&lt;/a&gt; is
documented as returning a string in &amp;ldquo;the following form: "X,Y,Width,Height"&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;It seems like this method is the complement to the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.rect.parse.aspx"&gt;Parse&lt;/a&gt;
method, which accepts the &amp;ldquo;string representation of the rectangle, in the form "x, y, width, height"&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;Unfortunately, while &lt;code&gt;Parse&lt;/code&gt; is culture-invariant (as documented), &lt;code&gt;ToString&lt;/code&gt; follows the .NET convention
of returning locale-sensitive results; you need to call the &lt;code&gt;ToString(IFormatProvider)&lt;/code&gt; overload
to produce a string in the "x,y,width,height" format (that can be accepted by &lt;code&gt;Parse&lt;/code&gt;).&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="n"&gt;Rect&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// &amp;quot;1.5,2,3.5,4&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// success&lt;/span&gt;

    &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentThread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentCulture&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CultureInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;de&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// or &amp;quot;es&amp;quot;, &amp;quot;fr&amp;quot;, etc.&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// &amp;quot;1,5;2;3,5;4&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// throws FormatException&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CultureInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvariantCulture&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// success&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;I filed a &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/details/716279/rect-tostring-behavior-doesnt-match-documentation"&gt;bug report&lt;/a&gt;,
even though this is arguably an error in the documentation, not in the .NET Framework itself.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/Ui8prnilc8Y" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Printing from .NET 3.5 in Windows 7</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2011/12/printing-from-net35-in-windows7.html" />
    <updated>2011-12-30T16:01:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2011/12/printing-from-net35-in-windows7</id>
    <content type="html">&lt;p&gt;Our users discovered a curious bug that appears to be caused by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Printing an &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.xps.packaging.xpsdocument.aspx"&gt;XpsDocument&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;that uses a font embedded in the application's resources&lt;/li&gt;
&lt;li&gt;from a .NET 3.5 application&lt;/li&gt;
&lt;li&gt;running on Windows 7&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The printed output looks like the following image; various glyphs are substituted
with larger sans-serif versions of themselves, causing a ransom-note-like appearance.&lt;/p&gt;

&lt;p&gt;&lt;img src="/blog/images/corrupted-print-output.png" alt="Corrupted print output from .NET 3.5" /&gt;&lt;/p&gt;

&lt;p&gt;We found that changing any one of the conditions above fixes the problem, but
unfortunately we need to print XPS using an embedded font, we're still using .NET 3.5,
and we have to run on Windows 7.&lt;/p&gt;

&lt;p&gt;Strangely enough, printing to the XPS Document Writer print driver, and then printing
that document with the XPS Viewer built into Windows 7 doesn't reproduce the problem;
it only happens when our app prints directly to an actual printer.&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;Workaround&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;I noticed that the XPS Viewer is a native application; this led me to
discover the Windows 7 &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ff686814.aspx"&gt;XPS Print API&lt;/a&gt;.
In conjunction with the (also new in Windows 7)
&lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd316976.aspx"&gt;XPS Document API&lt;/a&gt;,
this lets you print XPS documents from native code.&lt;/p&gt;

&lt;p&gt;We were able to solve the problem by automating the workaround described above:
our code writes its output to an &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.xps.xpsdocumentwriter.aspx"&gt;XpsDocumentWriter&lt;/a&gt;
backed by a temporary file (instead of a &lt;a href="http://msdn.microsoft.com/en-us/library/system.printing.printqueue.aspx"&gt;PrintQueue&lt;/a&gt;);
we then use the native APIs to print the temporary XPS file to the currently-selected printer.&lt;/p&gt;

&lt;p&gt;The first part is to define the native methods and COM interfaces we will need.
(And, as noted in this &lt;a href="http://stackoverflow.com/questions/6123507/xps-printing-from-windows-service"&gt;StackOverflow question&lt;/a&gt;,
the &lt;code&gt;IXpsPrintJobStream&lt;/code&gt; interface is either declared or implemented incorrectly, so we
have to call the &lt;code&gt;Close&lt;/code&gt; method as if it existed on &lt;code&gt;ISequentialStream&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;With those declared, the printing code can be written. This method (which should be called on a
background thread), prints a XPS file to a specific printer, returning &lt;code&gt;true&lt;/code&gt; if printing
succeeded. (If it fails, the application should fall back to the .NET printing APIs.)&lt;/p&gt;

&lt;p&gt;All the code below is also available &lt;a href="https://gist.github.com/1541424"&gt;in a gist&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NativeMethods&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="na"&gt;        [DllImport(&amp;quot;XpsPrint.dll&amp;quot;, ExactSpelling = true, CharSet = CharSet.Unicode)]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;StartXpsPrintJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;printerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;jobName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputFileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt; &lt;span class="n"&gt;progressEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;SafeWaitHandle&lt;/span&gt; &lt;span class="n"&gt;completionEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MarshalAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UnmanagedType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LPArray&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;printablePagesOn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;printablePagesOnCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;IXpsPrintJob&lt;/span&gt; &lt;span class="n"&gt;xpsPrintJob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;IXpsPrintJobStream&lt;/span&gt; &lt;span class="n"&gt;documentStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;IXpsPrintJobStream&lt;/span&gt; &lt;span class="n"&gt;printTicketStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;    [ComImport, Guid(&amp;quot;E974D26D-3D9B-4D47-88CC-3872F2DC3585&amp;quot;), ClassInterface(ClassInterfaceType.None)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;XpsOMObjectFactory&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;    [ComImport, Guid(&amp;quot;F9B2A685-A50D-4FC2-B764-B56E093EA0CA&amp;quot;), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;IXpsOMObjectFactory&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePackage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="na"&gt;        [return: MarshalAs(UnmanagedType.Interface)]&lt;/span&gt;
        &lt;span class="n"&gt;IXpsOMPackage&lt;/span&gt; &lt;span class="nf"&gt;CreatePackageFromFile&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;MarshalAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UnmanagedType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LPWStr&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;reuseObjects&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePackageFromStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateStoryFragmentsResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateDocumentStructureResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateSignatureBlockResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateRemoteDictionaryResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateRemoteDictionaryResourceFromStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePartResources&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateDocumentSequence&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePageReference&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePageFromStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateCanvas&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateGlyphs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateGeometry&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateGeometryFigure&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateMatrixTransform&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateSolidColorBrush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateColorProfileResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateImageBrush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateVisualBrush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateImageResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePrintTicketResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateFontResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateGradientStop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateLinearGradientBrush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateRadialGradientBrush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateCoreProperties&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateDictionary&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePartUriCollection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePackageWriterOnFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePackageWriterOnStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePartUri&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateReadOnlyStreamOnFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;    [ComImport, Guid(&amp;quot;18C3DF65-81E1-4674-91DC-FC452F5A416F&amp;quot;), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;IXpsOMPackage&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GetDocumentSequence&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetDocumentSequence&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GetCoreProperties&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetCoreProperties&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GetDiscardControlPartName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetDiscardControlPartName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GetThumbnailResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetThumbnailResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;WriteToFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;WriteToStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IXpsPrintJobStream&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;optimizeMarkupSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// NOTE: It appears that the IID for IXpsPrintJobStream specified in XpsPrint.h --  &lt;/span&gt;
    &lt;span class="c1"&gt;// MIDL_INTERFACE(&amp;quot;7a77dc5f-45d6-4dff-9307-d8cb846347ca&amp;quot;) -- is not correct, or the object&lt;/span&gt;
    &lt;span class="c1"&gt;// doesn&amp;#39;t implement QueryInterface correctly. However, we can QI for ISequentialStream and&lt;/span&gt;
    &lt;span class="c1"&gt;// successfully (at least in Windows 7 SP1 x86) call the Close method as if it existed on that&lt;/span&gt;
    &lt;span class="c1"&gt;// interface.&lt;/span&gt;
    &lt;span class="c1"&gt;// That is, we obtain the ISequentialStream interface, but work with it as the IXpsPrintJobStream interface.&lt;/span&gt;
    &lt;span class="c1"&gt;// Thanks to http://stackoverflow.com/questions/6123507/xps-printing-from-windows-service for this tip.&lt;/span&gt;
&lt;span class="na"&gt;    [ComImport, Guid(&amp;quot;0C733A30-2A1C-11CE-ADE5-00AA0044773D&amp;quot;), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;IXpsPrintJobStream&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ISequentialStream methods&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;MarshalAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UnmanagedType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LPArray&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;pv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;pcbRead&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;MarshalAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UnmanagedType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LPArray&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;pv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;pcbWritten&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// IXpsPrintJobStream methods&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;    [ComImport, Guid(&amp;quot;5AB89B06-8194-425F-AB3B-D7A96E350161&amp;quot;), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;IXpsPrintJob&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;IntPtr&lt;/span&gt; &lt;span class="nf"&gt;GetJobStatus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// Prints the specified XPS document to a printer using the native XPS Print API.&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name=&amp;quot;xpsFilePath&amp;quot;&amp;gt;The path to the XPS document.&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name=&amp;quot;printerName&amp;quot;&amp;gt;The printer name.&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name=&amp;quot;printTicket&amp;quot;&amp;gt;A PrintTicket with settings for this print job.&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; if the document was successfully printed; otherwise, &amp;lt;c&amp;gt;false&amp;lt;/c&amp;gt;.&amp;lt;/returns&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;remarks&amp;gt;This method should be called from a background thread.&amp;lt;/remarks&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;xpsFilePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;printerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PrintTicket&lt;/span&gt; &lt;span class="n"&gt;printTicket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// try to create the XPS Object Model factory (only available on Windows 7 and Vista with the Platform Update)&lt;/span&gt;
        &lt;span class="n"&gt;IXpsOMObjectFactory&lt;/span&gt; &lt;span class="n"&gt;xpsFactory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;xpsFactory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IXpsOMObjectFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;XpsOMObjectFactory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;COMException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// OS doesn&amp;#39;t support the XPS Document API&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;IXpsOMPackage&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// load the saved document as a native XpsOMPackage&lt;/span&gt;
            &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xpsFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreatePackageFromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xpsFilePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ManualResetEvent&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ManualResetEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// attempt to start the print job&lt;/span&gt;
                &lt;span class="n"&gt;IXpsPrintJob&lt;/span&gt; &lt;span class="n"&gt;printJob&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;IXpsPrintJobStream&lt;/span&gt; &lt;span class="n"&gt;docStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ticketStream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;hresult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NativeMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartXpsPrintJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;printerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jobTitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SafeWaitHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;printJob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;docStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;ticketStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="c1"&gt;// check for success (NOTE: checking HRESULT value directly instead of calling Marshal.ThrowExceptionForHR&lt;/span&gt;
                &lt;span class="c1"&gt;//   to avoid proliferation of &amp;#39;catch&amp;#39; blocks)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hresult&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// write the current printer settings to the print ticket stream&lt;/span&gt;
                    &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;ticketData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;printTicket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetXmlStream&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;bytesWritten&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="n"&gt;ticketStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticketData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ticketData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;bytesWritten&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;ticketStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

                    &lt;span class="c1"&gt;// write the XPS package to the document stream&lt;/span&gt;
                    &lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteToStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;docStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

                    &lt;span class="c1"&gt;// wait for printing to finish&lt;/span&gt;
                    &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitOne&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;COMException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// printing failed&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DllNotFoundException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// OS doesn&amp;#39;t support XPS Print API&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EntryPointNotFoundException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// OS doesn&amp;#39;t support XPS Print API&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// force the XPS package to be released, so that the temporary file can be deleted&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FinalReleaseComObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/YBJTTyhHap4" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Git Bash in Console2</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2011/06/git_bash_in_console2.html" />
    <updated>2011-06-09T10:26:00-07:00</updated>
    <id>http://code.logos.com/blog/blog/2011/06/git_bash_in_console2</id>
    <content type="html">&lt;p&gt;I started using &lt;a href="http://sourceforge.net/projects/console/"&gt;Console2&lt;/a&gt; after
reading Scott Hanselman’s &lt;a href="http://www.hanselman.com/blog/Conso%0Ale2ABetterWindowsCommandPrompt.aspx"&gt;recommendation&lt;/a&gt;. Not only can it display a regular
command prompt and PowerShell in tabs (as he describes), any console process
can be added. &lt;a href="http://code.google.com/p/msysgit/"&gt;msysgit&lt;/a&gt; users can add Git
Bash to by opening the Settings dialog and adding a tab with the following
properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Title:&lt;/strong&gt; Git Bash&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Icon:&lt;/strong&gt; C:\Program Files (x86)\Git\etc\git.ico&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shell:&lt;/strong&gt; C:\Windows\SysWOW64\cmd.exe /c ""C:\Program Files (x86)\Git\bin\sh.exe" --login -i"&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Startup dir:&lt;/strong&gt; C:\YourCode&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/P1ma_C_oCkI" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Generating a deterministic GUID</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2011/04/generating_a_deterministic_guid.html" />
    <updated>2011-04-13T18:31:00-07:00</updated>
    <id>http://code.logos.com/blog/blog/2011/04/generating_a_deterministic_guid</id>
    <content type="html">&lt;p&gt;Although a new GUID is typically created in order to provide a unique ID,
there are occasions when it’s useful for two different systems to generate the
same GUID independently. &lt;a href="http://www.ietf.org/rfc/rfc4122.txt"&gt;RFC 4122&lt;/a&gt;
provides an algorithm for deterministic creation of a GUID based on a
namespace ID (itself a GUID) and a name within that namespace. These name-
based GUIDs will never collide with GUIDs from other sources (e.g.,
&lt;a href="http://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx"&gt;Guid.NewGuid&lt;/a&gt;), and have a very (very) small chance of
colliding with other name-based GUIDs. As per section 4.3:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The UUIDs generated at different times from the same name in the same namespace MUST be equal.&lt;/li&gt;
&lt;li&gt;The UUIDs generated from two different names in the same namespace should be different (with very high probability).&lt;/li&gt;
&lt;li&gt;The UUIDs generated from the same name in two different namespaces should be different with (very high probability).&lt;/li&gt;
&lt;li&gt;If two UUIDs that were generated from names are equal, then they were generated from the same name in the same namespace (with very high probability).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Because the .NET Framework doesn’t provide a way to create these GUIDs, it’s
tempting to create a custom solution (e.g., using a MD5 hash as a GUID,
because it has the same number of bytes), but because that doesn’t follow the
rules of GUID creation, it’s not guaranteed to be unique with respect to other
GUIDs.&lt;/p&gt;

&lt;p&gt;The algorithm for generating these GUIDs is fairly straightforward; the most
complicated part may be converting the GUID to network byte order as specified
in the RFC. (It’s complicated enough that the RFC authors got it wrong; the
example given in Appendix B &lt;a href="http://www.rfc-editor.org/errata_search.php?rfc=4122&amp;amp;eid=1352"&gt;is incorrect&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;There are libraries to do this for
&lt;a href="http://docs.python.org/library/uuid.html"&gt;Python&lt;/a&gt; and
&lt;a href="http://www.boost.org/doc/libs/1_43_0/libs/uuid/uuid.html"&gt;C++&lt;/a&gt;; I didn’t find
one for .NET, so I wrote &lt;a href="https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/GuidUtility.cs"&gt;GuidUtility.Create&lt;/a&gt; which implements the
RFC 4122 rules. Using it is simple (once you’ve decided on the namespace ID to
use):&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;guid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GuidUtility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GuidUtility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DnsNamespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;code.logos.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/4x6nwIimcyY" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Binary Patching with bsdiff in C#</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2010/12/binary_patching_with_bsdiff.html" />
    <updated>2010-12-29T16:00:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2010/12/binary_patching_with_bsdiff</id>
    <content type="html">&lt;p&gt;&lt;a href="http://www.daemonology.net/bsdiff/"&gt;bsdiff&lt;/a&gt; and bspatch are tools for
building and applying patches to binary files. If the files are reasonably
similar (e.g., built from the same source code), a patch that can transform v1
of a file into v2 is often significantly smaller than downloading the entire
v2 file. According to &lt;a href="http://www.daemonology.net/papers/bsdiff.pdf"&gt;Naïve Differences of Executable
Code&lt;/a&gt; (the paper that introduced
the algorithm), compression ratios of 10x or more are typically achieved.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://www.daemonology.net/bsdiff/bsdiff-4.3.tar.gz"&gt;reference
implementation&lt;/a&gt; is
written in C and uses  &lt;a href="http://bzip.org/"&gt;bzip2&lt;/a&gt; to compress chunks in the
patch file. I ported the algorithm to C# and used
&lt;a href="http://www.icsharpcode.net/opensource/sharpziplib/"&gt;#ziplib&lt;/a&gt; for bzip2
support.&lt;/p&gt;

&lt;p&gt;The primary file is &lt;a href="https://github.com/LogosBible/bsdiff.net/blob/master/src/bsdiff/BinaryPatchUtility.cs"&gt;BinaryPatchUtility.cs&lt;/a&gt;; the entire project (with
bsdiff and bspatch front ends) is &lt;a href="https://github.com/LogosBible/bsdiff.net"&gt;available at
github&lt;/a&gt;. (Note that if you just want
to run bsdiff from the command prompt, a &lt;a href="http://sites.inka.de/tesla/others.html#bsdiff"&gt;Windows
port&lt;/a&gt; is already available.
This project is designed for reuse within another program, under the same
license as the original bsdiff code.)&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/rS2AsmJtzdw" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>DirectoryInfo.GetFiles improved in .NET 4</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2010/12/directoryinfogetfiles_improved_in_net_4.html" />
    <updated>2010-12-16T20:30:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2010/12/directoryinfogetfiles_improved_in_net_4</id>
    <content type="html">&lt;p&gt;A nice improvement in .NET 4 is that the following code runs significantly
faster than it did under .NET 3.5:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DirectoryInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folderPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FileInfo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;In .NET 3.5, the &lt;code&gt;Length&lt;/code&gt; property (as well as most of the other properties on
&lt;code&gt;FileInfo&lt;/code&gt;) is fetched lazily; accessing the property hits the filesystem
again for each file returned by GetFiles, incurring a substantial speed
penalty. In .NET 4, &lt;a href="http://msdn.microsoft.com/en-us/library/4cyf24ss.aspx"&gt;GetFiles&lt;/a&gt; uses the information already returned by the OS when
enumerating the contents of the directory to pre-populate the values of the
FileInfo properties, avoiding subsequent filesystem accesses.&lt;/p&gt;

&lt;p&gt;For a folder containing several thousand files, the .NET 4 implementation can
be from three times (on a local drive) to 50 times (on a network path) faster.&lt;/p&gt;

&lt;p&gt;For more information on this and other changes, see Justin Van Patten's MSDN
magazine article, &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee428166.aspx"&gt;What's New in the Base Class Libraries in .NET Framework
4&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/yK_VeuneolA" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Fixing C++ projects that always rebuild</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2010/12/fixing_c_projects_that_always_rebuild.html" />
    <updated>2010-12-06T15:53:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2010/12/fixing_c_projects_that_always_rebuild</id>
    <content type="html">&lt;p&gt;After upgrading to Visual Studio 2010, one of our C++ projects would always be
built, even if none of its files changed. When setting MSBuild output
verbosity to "Normal", the Build output window would show:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1&amp;gt;------ Build started: Project: SomeLib, Configuration: Release Win32 ------ 
1&amp;gt;InitializeBuildStatus: 
1&amp;gt;  Creating ".\Release\SomeLib.unsuccessfulbuild" because "AlwaysCreate" was specified. 
...
1&amp;gt;Build succeeded. 
1&amp;gt; 
1&amp;gt;Time Elapsed 00:00:00.47 
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This occurred even though none of the files in that project had changed.&lt;/p&gt;

&lt;p&gt;This &lt;a href="http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/38c08137-3bb0-4143-b97f-72d077646318"&gt;forum thread&lt;/a&gt; and
&lt;a href="https://connect.microsoft.com/VisualStudio/feedback/details/574245/alwayscreate-needs-documentation-or-vs10-fix"&gt;Connect issue&lt;/a&gt; describe the problem and state
that it's usually caused by referencing a .h file in the project that doesn't
exist on disk; the build system in VS2010 then assumes the project is out-of-
date and builds it. The forum thread references a blog post about &lt;a href="http://blogs.msdn.com/b/vsproject/archive/2009/07/21/enable-c-project-system-logging.aspx"&gt;enabling
C++ project system
logging&lt;/a&gt; in order to diagnose the problem, but it didn't
help me identify the missing file. Instead, I wrote the following script to
parse the project file and check for missing files:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="c1"&gt;// set this to your project&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@&amp;quot;C:\Path\To\MyProject.vcxproj&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;XDocument&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;XDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;XNamespace&lt;/span&gt; &lt;span class="n"&gt;msbuild&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;XNamespace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://schemas.microsoft.com/developer/msbuild/2003&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;present&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;missing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;folder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDirectoryName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;XElement&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Elements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msbuild&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;ItemGroup&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Elements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msbuild&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;ClInclude&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Include&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;itemPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;itemPath&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;missing&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;present&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{0} files present, {1} missing.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;present&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;missing&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;You could change "ClInclude" to "ClCompile" to look for missing C++ files (but
this should already be a build error) or to "None" to find missing non-source
files.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/KruliPW8IAo" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Coroutines with C# 5's await</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2010/10/coroutines_with_c_5s_await.html" />
    <updated>2010-10-30T10:30:00-07:00</updated>
    <id>http://code.logos.com/blog/blog/2010/10/coroutines_with_c_5s_await</id>
    <content type="html">&lt;p&gt;C# 5's new "await" keyword is not just for orchestrating and controlling
concurrency on multiple threads; it can also be used to introduce "exotic"
control flow, such as &lt;a href="http://en.wikipedia.org/wiki/Coroutine"&gt;coroutines&lt;/a&gt;
(see also &lt;a href="http://www.c2.com/cgi/wiki?CoRoutine"&gt;here&lt;/a&gt;), to a single-threaded
C# program.&lt;/p&gt;

&lt;p&gt;I was trying to find a really good sample coroutine problem to solve with
"await", but all the ones I found given as standard examples (e.g., &lt;a href="http://www.c2.com/cgi/wiki?OddWordProblem"&gt;odd word
problem&lt;/a&gt;, &lt;a href="http://www.c2.com/cgi/wiki?SameFringeProblem"&gt;same fringe
problem&lt;/a&gt;) could be easily (and I
think more suitably) solved with C# 2.0 iterators (because the data only flows
one way between the sub/coroutines needed to solve those problems).&lt;/p&gt;

&lt;p&gt;The idea I finally came up with was of merging two ordered sequences of
numbers. In C# 2.0, you could write a Merge method that creates an enumerator
for each input sequence, tracks whether each sequence still has items, and
compares the heads of each sequence to determine which is smaller. This is a
lot of code, and the scaffolding obscures the core of the method, which is the
comparison of the two items:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;MergeWithEnumerators&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;leftSequence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;rightSequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// enumerate the sequences&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;leftSequence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetEnumerator&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rightSequence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetEnumerator&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// start the enumeration&lt;/span&gt;
            &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;leftHasItems&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MoveNext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;rightHasItems&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MoveNext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;// continue until out of items&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leftHasItems&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;rightHasItems&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// determine whether to output from left or right&lt;/span&gt;
                &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;outputLeft&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leftHasItems&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;rightHasItems&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;outputLeft&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;
                    &lt;span class="n"&gt;outputLeft&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;leftHasItems&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="c1"&gt;// output correct element&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputLeft&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;leftHasItems&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MoveNext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;rightHasItems&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MoveNext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;(I've used Console.WriteLine for simplicity; in the real world, you'd probably
want this method to return IEnumerable&lt;int&gt; and yield return the merged
elements.)&lt;/p&gt;

&lt;p&gt;In C# 5, the merge could be written with coroutines. Imagine two Merge methods
running in an interleaved fashion (not simultaneously), each processing one
input sequence. If the methods can know what the smallest current item in the
other sequence is, then their implementation is trivial: for each of the
values in their own sequence, compare it to the smallest value from the other
sequence. If it's smaller, print it; if not, switch to the other method and
let it processs its sequence:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="c1"&gt;// The Merge coroutine is run on each of the two input sequences.&lt;/span&gt;
    &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int?&lt;/span&gt; &lt;span class="n"&gt;smallestInOther&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// process our entire sequence&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// switch to the other if it has smaller values than we do&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;smallestInOther&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;smallestInOther&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;SwitchToOther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// our value is smaller, print it&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Of course, this code can't stand alone; it needs a scheduler that will start
both the methods, and also an implementation of SwitchToOther, which will save
this method's "resume" action, and invoke it later when the second method
switches back to this one. There's a lot of code here, but much of it is just
the boilerplate that's required to support the "await" keyword (GetAwaiter,
BeginAwait, EndAwait).&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="c1"&gt;// continuations (queued up by &amp;quot;await SwitchToOther&amp;quot;) that are ready to be resumed&lt;/span&gt;
    &lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SwitchAwaiter&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;awaiters&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SwitchAwaiter&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// the smallest value in each input sequence; this needs to be passed to the other Merge method&lt;/span&gt;
    &lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;smallestValues&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Merges two sequences using coroutines.&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// start each of the methods running&lt;/span&gt;
        &lt;span class="n"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MinValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;smallestValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dequeue&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="c1"&gt;// keep switching between them as requested&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;awaiters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;SwitchAwaiter&lt;/span&gt; &lt;span class="n"&gt;switchAwaiter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;awaiters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dequeue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;// the last switch will have no smallest value (because the Merge method finished its&lt;/span&gt;
            &lt;span class="c1"&gt;// enumeration, and exited); we pass &amp;#39;null&amp;#39; as a sentinel&lt;/span&gt;
            &lt;span class="n"&gt;switchAwaiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;smallestValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;smallestValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dequeue&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Allows a method to switch to another method by &amp;#39;awaiting&amp;#39; the returned value.&lt;/span&gt;
    &lt;span class="n"&gt;SwitchAwaiter&lt;/span&gt; &lt;span class="nf"&gt;SwitchToOther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;smallest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// this method is called by &amp;#39;await&amp;#39;, so we need to return a type that implements &amp;#39;GetAwaiter&amp;#39;&lt;/span&gt;
        &lt;span class="n"&gt;SwitchAwaiter&lt;/span&gt; &lt;span class="n"&gt;switchAwaiter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SwitchAwaiter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// queue this as the method to switch to in the future&lt;/span&gt;
        &lt;span class="n"&gt;awaiters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;switchAwaiter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;smallestValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;smallest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;switchAwaiter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SwitchAwaiter&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;SwitchAwaiter&lt;/span&gt; &lt;span class="nf"&gt;GetAwaiter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// &amp;#39;GetAwaiter&amp;#39; must return an object that implements &amp;#39;BeginAwait&amp;#39; and &amp;#39;EndAwait&amp;#39;&lt;/span&gt;
            &lt;span class="c1"&gt;// for simplicity, it can be this same object&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// &amp;#39;BeginAwait&amp;#39; is called to &amp;quot;suspend&amp;quot; the method executing the &amp;#39;await&amp;#39;.&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;BeginAwait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// save the action that will be used to resume the method&lt;/span&gt;
            &lt;span class="n"&gt;m_resume&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;// &amp;#39;true&amp;#39; means that the awaiting method needs to return control to its caller and&lt;/span&gt;
            &lt;span class="c1"&gt;// that it will be resumed later on&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int?&lt;/span&gt; &lt;span class="n"&gt;EndAwait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// once we resume the method, &amp;#39;EndAwait&amp;#39; supplies a value to it (from the &amp;#39;await&amp;#39; keyword)&lt;/span&gt;
            &lt;span class="c1"&gt;// in this case, we give it the smallest value from the other Merge method&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;m_smallest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// &amp;#39;Resume&amp;#39; returns control to the method that executed &amp;#39;await SwitchToOther&amp;#39;. &amp;#39;smallest&amp;#39; is the&lt;/span&gt;
        &lt;span class="c1"&gt;// smallest value in the sequence being enumerated by the other method.&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Resume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int?&lt;/span&gt; &lt;span class="n"&gt;smallestInOther&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;m_smallest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;smallestInOther&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;m_resume&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;m_resume&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int?&lt;/span&gt; &lt;span class="n"&gt;m_smallest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;At the end, was it worth it? Yes, the Merge method itself is shorter and
concisely expresses its purpose, but there's a lot of supporting code
required, which may or may not be reusable to solve different problems. This
method is also not scalable: if we wanted to merge three (or more) sequences,
it's clearly wrong to have each coroutine pick which of its peers it's going
to switch to; in that case, we'd definitely want a single consumer that's
picking the overall next smallest value (perhaps using a min heap for
efficiency if there are lots of sequences being merged).&lt;/p&gt;

&lt;p&gt;So while it was an interesting challenge to interleave the execution of two
methods on the same thread using "await", it isn't the best solution to this
particular problem. (Maybe there is a similar problem for which "await" really
is the killer solution; if you know of one, I'd love to hear about it.)&lt;/p&gt;

&lt;p&gt;That's not to say that "await" is useless; far from it! There are many other
problems (that we've solved more or less well in the Logos code today) that
could be solved far more elegantly and concisely with the "await" keyword; I'm
definitely looking forward to using it.&lt;/p&gt;

&lt;p&gt;P.S. As an exercise for the reader, change "Console.WriteLine(value);" (in the
first Merge method) to "await Output(value);" and rewrite the second Merge
method to "yield return" the merged values, so that the merge can happen
lazily.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/7KAoGvg2zdE" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Overriding GetHashCode for value types</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2010/10/overriding_gethashcode_for_value_types.html" />
    <updated>2010-10-04T15:36:00-07:00</updated>
    <id>http://code.logos.com/blog/blog/2010/10/overriding_gethashcode_for_value_types</id>
    <content type="html">&lt;p&gt;I’ve &lt;a href="../02/creating_equatable_objects.html"&gt;written before&lt;/a&gt; that value types
should override Object.Equals for performance reasons. GetHashCode should be
overridden at the same time (for symmetry), but I’ve just learnt another good
reason to override GetHashCode: the default implementation has a
&lt;a href="http://stackoverflow.com/questions/3841602/why-is-valuetype-gethashcode-implemented-like-it-is/3842515#3842515"&gt;bug&lt;/a&gt;
when your struct contains a nested
value type for which value equality is not the same as bitwise equality.&lt;/p&gt;

&lt;p&gt;As per Hans Passant’s &lt;a href="http://stackoverflow.com/questions/3841602/why-is-valuetype-gethashcode-implemented-like-it-is/3842515#3842515"&gt;detailed
comment&lt;/a&gt;,
the default ValueType.GetHashCode implementation (on the Microsoft CLR) XORs the bits of
the struct together if it contains no reference types and has no padding.&lt;/p&gt;

&lt;p&gt;Unfortunately, if the struct contains a member that can have two different bit
patterns that represent the same logical value, this will generate different
hash codes for values that should be considered equal. (The default Equals
implementation will call the Equals methods of the nested types, so it is not
subject to this bug.) The most common example is decimal: 1m and 1.0m have
different bit representations in memory, so the following program produces
rather unexpected output:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Test&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="n"&gt;Test&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1.0&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetHashCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetHashCode&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Test&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;If you’re implementing a value type that will ever be used as a key in a
hashtable, &lt;strong&gt;always override Object.GetHashCode&lt;/strong&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/c1dxWF-wOOk" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Fixing Debug &gt; Exceptions settings programmatically</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2010/09/fixing_debug_exceptions_settings_programmatically.html" />
    <updated>2010-09-08T09:55:00-07:00</updated>
    <id>http://code.logos.com/blog/blog/2010/09/fixing_debug_exceptions_settings_programmatically</id>
    <content type="html">&lt;p&gt;I have a love/hate relationship with the Visual Studio Debug &gt; Exceptions
dialog (as I have &lt;a href="../01/saving_debug_exceptions_settings.html"&gt;written
previously&lt;/a&gt;). I love the
functionality it provides (dropping into the debugger when an exception
occurs) but I hate, well, pretty much everything else about it. (And, sadly,
it appears to be completely unchanged in Visual Studio 2010.)&lt;/p&gt;

&lt;p&gt;&lt;img src="/blog/WindowsLiveWriter/SavingDebugExceptionssettings_EFB4/Exceptions_6.png" alt="Visual Studio Exceptions dialog" /&gt;&lt;/p&gt;

&lt;p&gt;Visual Studio persists in losing the settings I painstakingly set up (for our
solution, I need to add two standard exception types that are mysteriously
absent from its default list, and uncheck five exceptions that are thrown a
lot by the framework but don't indicate any serious problem), which is very
frustrating.&lt;/p&gt;

&lt;p&gt;So I was very excited today to discover that these settings are automatable
through the &lt;a href="http://msdn.microsoft.com/en-us/library/envdte90.exceptionsettings(v=VS.90"&gt;ExceptionSettings&lt;/a&gt;.aspx) interface exposed by the
EnvDTE90 assembly (i.e., Visual Studio core automation). I immediately fired
up the VS macro editor and wrote a VB macro that would iterate through all of
the exceptions and turn on "Break when thrown" for each of them. I ran it...
and waited... and waited... and gave up and terminated devenv.exe. It turns
out that (running at 100% CPU on a Core i7), the COM interface can modify
approximately &lt;em&gt;one checkbox per second&lt;/em&gt;. It would probably take 10 minutes to
check all the checkboxes in this dialog (during which time, of course, the VS
UI is completely frozen).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/vsdebug/thread/b0efc1fd-879e-4882-8992-c0ecd4cd980f#0684ef8c-fac6-4cf2-82e1-dce6b708ec14"&gt;Others&lt;/a&gt;
have &lt;a href="http://www.wintellect.com/CS/blogs/jrobbins/archive/2009/04/03/customizing-exception-handling-in-the-vs-debugger.aspx#18269"&gt;noticed&lt;/a&gt;
this, but no one has found a solution. A &lt;a href="http://stackoverflow.com/questions/958011/toggle-break-when-an-exception-is-thrown-using-macro-or-keyboard-shortcut"&gt;StackOverflow
answer&lt;/a&gt;
comes close but still doesn't solve the problem.&lt;/p&gt;

&lt;p&gt;I now use a hybrid solution: I open the dialog and check each top-level
"Thrown" checkbox to check all its children. I close the dialog then run a
macro which adds the missing exceptions and unchecks the handful of exceptions
I don't want to break on. It still takes 15 seconds to run, but it's far
better than having to do it by hand.&lt;/p&gt;

&lt;p&gt;To use this code, open the Macro Explorer and right-click to add a new module
(call it "ExceptionsModule"). Paste the following code in, then right-click
the "FixExceptions" macro and choose Run to execute it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Added the GetOrCreateException function to deal with the situation where VS resets to factory defaults and removes previously-added exceptions.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="vbnet"&gt;    &lt;span class="k"&gt;Imports&lt;/span&gt; &lt;span class="n"&gt;EnvDTE90&lt;/span&gt;
    &lt;span class="k"&gt;Imports&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InteropServices&lt;/span&gt;
    &lt;span class="k"&gt;Public&lt;/span&gt; &lt;span class="k"&gt;Module&lt;/span&gt; &lt;span class="n"&gt;ExceptionsModule&lt;/span&gt;
        &lt;span class="k"&gt;Public&lt;/span&gt; &lt;span class="k"&gt;Function&lt;/span&gt; &lt;span class="n"&gt;GetGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ByVal&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="n"&gt;ExceptionSettings&lt;/span&gt;
            &lt;span class="k"&gt;Dim&lt;/span&gt; &lt;span class="n"&gt;dbg&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="n"&gt;Debugger3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DTE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Debugger&lt;/span&gt;
            &lt;span class="n"&gt;GetGroup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dbg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExceptionGroups&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;End&lt;/span&gt; &lt;span class="k"&gt;Function&lt;/span&gt;

        &lt;span class="c"&gt;&amp;#39; Gets or creates the exception with the specified name in the specified group.&lt;/span&gt;
        &lt;span class="k"&gt;Public&lt;/span&gt; &lt;span class="k"&gt;Function&lt;/span&gt; &lt;span class="n"&gt;GetOrCreateException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ByVal&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="n"&gt;ExceptionSettings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;ByVal&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="n"&gt;ExceptionSetting&lt;/span&gt;
            &lt;span class="k"&gt;Try&lt;/span&gt;
                &lt;span class="n"&gt;GetOrCreateException&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;Catch&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="n"&gt;COMException&lt;/span&gt; &lt;span class="k"&gt;When&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ErrorCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2147352565&lt;/span&gt; &lt;span class="c"&gt;&amp;#39; DISP_E_BADINDEX&lt;/span&gt;
                &lt;span class="n"&gt;GetOrCreateException&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;End&lt;/span&gt; &lt;span class="k"&gt;Try&lt;/span&gt;
        &lt;span class="k"&gt;End&lt;/span&gt; &lt;span class="k"&gt;Function&lt;/span&gt;

        &lt;span class="c"&gt;&amp;#39; Gets or creates (with the specified name) the exception with the specified code in the specified group.&lt;/span&gt;
        &lt;span class="k"&gt;Public&lt;/span&gt; &lt;span class="k"&gt;Function&lt;/span&gt; &lt;span class="n"&gt;GetOrCreateException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ByVal&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="n"&gt;ExceptionSettings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;ByVal&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;ByVal&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="kt"&gt;UInteger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="n"&gt;ExceptionSetting&lt;/span&gt;
            &lt;span class="k"&gt;Try&lt;/span&gt;
                &lt;span class="n"&gt;GetOrCreateException&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ItemFromCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;Catch&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="n"&gt;COMException&lt;/span&gt; &lt;span class="k"&gt;When&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ErrorCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2147352565&lt;/span&gt; &lt;span class="c"&gt;&amp;#39; DISP_E_BADINDEX&lt;/span&gt;
                &lt;span class="n"&gt;GetOrCreateException&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;End&lt;/span&gt; &lt;span class="k"&gt;Try&lt;/span&gt;
        &lt;span class="k"&gt;End&lt;/span&gt; &lt;span class="k"&gt;Function&lt;/span&gt;

        &lt;span class="k"&gt;Public&lt;/span&gt; &lt;span class="k"&gt;Sub&lt;/span&gt; &lt;span class="n"&gt;FixExceptions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;Dim&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="n"&gt;ExceptionSettings&lt;/span&gt;
            &lt;span class="k"&gt;Dim&lt;/span&gt; &lt;span class="n"&gt;setting&lt;/span&gt; &lt;span class="ow"&gt;As&lt;/span&gt; &lt;span class="n"&gt;ExceptionSetting&lt;/span&gt;

            &lt;span class="c"&gt;&amp;#39; Common Language Runtime Exceptions&lt;/span&gt;
            &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Common Language Runtime Exceptions&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;For&lt;/span&gt; &lt;span class="k"&gt;Each&lt;/span&gt; &lt;span class="n"&gt;exceptionName&lt;/span&gt; &lt;span class="ow"&gt;In&lt;/span&gt; &lt;span class="k"&gt;New&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
                    &lt;span class="s"&gt;&amp;quot;System.FormatException&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
                    &lt;span class="s"&gt;&amp;quot;System.NotSupportedException&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
                    &lt;span class="s"&gt;&amp;quot;System.Configuration.ConfigurationErrorsException&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
                    &lt;span class="s"&gt;&amp;quot;System.Deployment.Application.InvalidDeploymentException&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
                    &lt;span class="s"&gt;&amp;quot;System.IO.FileNotFoundException&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
                    &lt;span class="s"&gt;&amp;quot;System.Net.WebException&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;setting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetOrCreateException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exceptionName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBreakWhenThrown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;Next&lt;/span&gt;

            &lt;span class="c"&gt;&amp;#39; Managed Debugging Assistants&lt;/span&gt;
            &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Managed Debugging Assistants&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;setting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;BindingFailure&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBreakWhenThrown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c"&gt;&amp;#39; Win32 Exceptions&lt;/span&gt;
            &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Win32 Exceptions&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;setting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetOrCreateException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;RPC Canceled&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1818&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBreakWhenThrown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;End&lt;/span&gt; &lt;span class="k"&gt;Sub&lt;/span&gt;
    &lt;span class="k"&gt;End&lt;/span&gt; &lt;span class="k"&gt;Module&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;For more on scripting this dialog, see John Robbins' post, &lt;a href="http://www.wintellect.com/CS/blogs/jrobbins/archive/2009/04/03%0A/customizing-exception-handling-in-the-vs-debugger.aspx"&gt;Customizing
Exception Handler in the VS
Debugger&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/lb45faQQkkM" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  

</feed>

