<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Alois Kraus</title>
        <link>http://geekswithblogs.net/akraus1/Default.aspx</link>
        <description>blog</description>
        <language>en-US</language>
        <copyright>Alois Kraus</copyright>
        <managingEditor>akraus1@gmx.de</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <image>
            <title>Alois Kraus</title>
            <url>http://geekswithblogs.net/images/RSS2Image.gif</url>
            <link>http://geekswithblogs.net/akraus1/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>Enterprise Library 4 Released - And It Is Fast!</title>
            <link>http://geekswithblogs.net/akraus1/archive/2008/05/20/122277.aspx</link>
            <description>&lt;p&gt;In case you have not noticed the Patterns &amp;amp; Practices Team has released the greatest and latest version of the Enterprise Library. More info's can be found at &lt;a href="http://blogs.msdn.com/agile/archive/2008/05/16/enterprise-library-4-0-for-visual-studio-2008-released.aspx"&gt;Grigory Melniks blog&lt;/a&gt;. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;What’s New in v4.0?&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;This release of Enterprise Library includes the following:&lt;/p&gt;    &lt;p&gt;– Integration with the Unity Application Block &lt;/p&gt;    &lt;p&gt;– Windows Management Instrumentation (WMI) 2.0 support and improved instrumentation &lt;/p&gt;    &lt;p&gt;– Performance improvements (particularly, in the Logging Application Block)&lt;/p&gt;    &lt;p&gt;– Pluggable Cache Managers &lt;/p&gt;    &lt;p&gt;– Visual Studio 2008 support &lt;/p&gt;    &lt;p&gt;– Bug fixes&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Unity looks cool but I was not able to see any noticeable startup performance gain. The usage of dynamic code generation (Build Plans) to invoke ctors and properties seems not to pay off when we create from each type only one or two instances.  WMI looks nice but you need this stuff only if your architecture does not have central configuration mechanism. Alternatively you could use a custom configuration source which gets its configuration from somewhere else (WCF?) quite easily. The Visual Studio 2008 integration is (of course) seamless as expected. One really cool thing is buried in the performance improvements section where the Logging Application Block has got some attention. As noted in my previous article &lt;a href="http://geekswithblogs.net/akraus1/archive/2008/01/14/118543.aspx"&gt;Really Fast Formatting With Enterprise Library&lt;/a&gt; there are massive performance gains possible by doing some intelligent preprocessing of the TextFormatter templates and getting into a more functional style of programming. The formatting performance of the new Enterprise Library is &amp;gt;10 times better. It seems that these improvements were not on the original road map (the March CTP did not contain any improvements in this area) but my proposal was taken and implemented.&lt;/p&gt;  &lt;p&gt;I did try to extend the improved TextFormatter but did give up soon because this portion of the Enterprise Library plays a little closed source here and does not let me override the formatting of any existing token. Fortunately a little copy &amp;amp; paste did solve this issue quite nicely (not the best pattern of code reuse but it works). By applying the new formatting method via delegates I was able to get performance gains over a factor 2 in logging throughput which helps scalability a lot. Come and get it and see it for yourself.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122277"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122277" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/akraus1/aggbug/122277.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Alois Kraus</dc:creator>
            <guid>http://geekswithblogs.net/akraus1/archive/2008/05/20/122277.aspx</guid>
            <pubDate>Wed, 21 May 2008 00:07:03 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/akraus1/comments/122277.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/akraus1/archive/2008/05/20/122277.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/akraus1/comments/commentRss/122277.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/akraus1/services/trackbacks/122277.aspx</trackback:ping>
        </item>
        <item>
            <title>Enterprise Library 4 CTP - Improvements/Logging Application Block</title>
            <link>http://geekswithblogs.net/akraus1/archive/2008/04/09/121148.aspx</link>
            <description>&lt;p&gt;The Enterprise Library 4 CTP and the feature list can be found at the &lt;a href="http://www.codeplex.com/entlib"&gt;Codeplex Home page&lt;/a&gt;. &lt;/p&gt;  &lt;h4&gt;&lt;strong&gt;General Features of Entlib 4 (Excerpt from Release Notes)&lt;/strong&gt;&lt;/h4&gt;  &lt;blockquote&gt;   &lt;p&gt;· Enterprise Library 4.0 takes advantage of the improved features in the .NET WMI 2.0 API to provide update capability for configuration exposed through the Manageable Configuration Source. Objects defined in the Enterprise Library configuration, such as databases, trace listeners, and cache backing stores, are exposed through WMI as a set of classes that you can query and update. Providing that you have the relevant Windows permission to update WMI values, any changes you make to the properties of these classes are reflected back through the Manageable Configuration Source and update the configuration information exposed to your application. Changes do not affect the original configuration file contents and may be overridden by Group Policy.&lt;/p&gt;    &lt;p&gt;· In version 4.0, Enterprise Library has the Allow Partially-Trusted Caller attribute (APTCA) on all assemblies. This means that you can call the methods of Enterprise Library and the application blocks from an application running in a partial trust environment. You can do this with the signed assemblies provided with Enterprise Library. There is no longer any requirement, as there was in version 3.x, to recompile the source code and the source code for Object Builder then either use the unsigned binaries or strong-name them yourself.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That is good news for all medium trust ASP.NET web developers and Active Directory administrators that want to have an easy way to configure the application blocks in a central way.&lt;/p&gt;  &lt;h4&gt;&lt;strong&gt;New Logging Application Features (Excerpt from Release Notes)&lt;/strong&gt;&lt;/h4&gt;  &lt;blockquote&gt;   &lt;p&gt;· The application block now allows you to specify a value for the &lt;b&gt;Filter&lt;/b&gt; property of each of the Trace Listeners. This property applies a filter that selects the level of message that it will detect. The valid values are &lt;b&gt;All&lt;/b&gt;, &lt;b&gt;Off&lt;/b&gt;, &lt;b&gt;Critical&lt;/b&gt;, &lt;b&gt;Error&lt;/b&gt;, &lt;b&gt;Warning&lt;/b&gt;, &lt;b&gt;Information&lt;/b&gt;, &lt;b&gt;Verbose&lt;/b&gt;, and &lt;b&gt;Activity Tracing&lt;/b&gt;. The setting effectively means "the specified level and everything more important." For example, the Warning setting will detect warnings, errors, and critical events. The default is &lt;b&gt;All&lt;/b&gt;, which means that the behavior of the listener is the same as in previous versions of Enterprise Library if a value is not specified in the configuration.&lt;/p&gt;    &lt;p&gt;· The application block now allows you to specify that the &lt;b&gt;RollingFlatFileTraceListener&lt;/b&gt; will start a new file at midnight every day. To use this behavior, set the value of the &lt;b&gt;RollInterval&lt;/b&gt; property of the &lt;b&gt;RollingFlatFileTraceListener&lt;/b&gt; to Midnight.&lt;/p&gt;    &lt;p&gt;· The application block contains performance improvements that include the following:&lt;/p&gt;    &lt;p&gt;◦ Delayed gathering of context information until actually requested (except in distributed scenarios where context information is gathered even if not used).&lt;/p&gt;    &lt;p&gt;◦ Automatic flushing is now configurable. However, the default is to flush always, which means that the behavior of the listener is the same as in previous versions of Enterprise Library if a value is not specified in the configuration. To disable automatic flushing, set the &lt;b&gt;AutoFlush&lt;/b&gt; property of the Log Source to &lt;b&gt;True&lt;/b&gt;. It is then your responsibility to ensure that all entries are flushed to the target, especially if an exception or failure occurs in the application. Otherwise, you will lose any cached logging information not yet written to the target.&lt;/p&gt;    &lt;p&gt;· Log file names now support the use of environment variables. You can include environment variables such as %WINDIR%, %TEMP%, and %USERPROFILE% in the &lt;b&gt;Filename&lt;/b&gt; property of the Flat File Trace Listener, Rolling Flat File Trace Listener, and XML Trace Listener.&lt;/p&gt;    &lt;p&gt;The application block implements several new performance counters that you can use to monitor performance and operations. The new counters are Total Logging Events Raised, Total Trace Listener Entries Written, and Total Trace Operations Started.&lt;/p&gt; &lt;/blockquote&gt;  &lt;h4&gt;&lt;strong&gt;First Impressions&lt;/strong&gt;&lt;/h4&gt;  &lt;p&gt;The startup performance improvements with &lt;a href="http://www.codeplex.com/unity"&gt;Unity&lt;/a&gt; (which is already released) are not done yet but I hope that this will help to make the usage of the application blocks nearly invisible. The new dependency injection mechanism which uses reflection like ObjectBuilder (slow) but uses dynamically generated IL code to call the actual constructors/getter/setter methods. That increases the object creation performance dramatically. I hope that this will make a noticeable difference in a real world application.&lt;/p&gt;  &lt;p&gt;After doing a quick diff I found some improvements in the Logging Application Block. They do mainly concern the configuration via WMI and group policies with ADM templates. That enables to query and deploy logging configuration via an Active Directory without changing a physical file on the target machines. That is a nice feature but I have to yet to see if that does work in all scenarios. Low privileged users do not always have full WMI access which could hinder the usage of the new feature in low trust environments. &lt;/p&gt;  &lt;p&gt;Writing to a log file seems to be very easy but it did take over three years (Jan. 2005 was the first release) to support environment variables in file names. The delivered code quality was always very good but why on earth did it take so long? Working agile with a very strict timeline does enable the P&amp;amp;P team to deliver top features on time but low priority features such as this one have been dropped. That is no problem since the community did deliver very quickly the missing features such as the &lt;a href="http://bloggingabout.net/blogs/erwyn/articles/rolling_file_trace_listener.aspx"&gt;Rolling File Trace Listener&lt;/a&gt; from Erwyn van der Meer which is in my opinion still the one of the cleanest implementations of a Rolling File Trace Listener. What I really miss is a backflow of great community extensions to the Enterprise Library main code base. &lt;/p&gt;  &lt;p&gt;A really nifty feature of the new Rolling File Trace Listener is the roll interval Midnight to enable to start a new log file at every day. Although one should not expect a roll over exactly at midnight since the roll over is only performed when the next log call arrives after the time span has elapsed.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h4&gt;&lt;strong&gt;Logging Application Block Performance&lt;/strong&gt;&lt;/h4&gt;  &lt;p&gt;The creation of LogEntry objects has become dramatically faster since the current values are only read when needed. That is good but not perfect (yet). The main observations I did make&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;LogEntry: Process Id, Process Name and AppDomain Name will never change during the lifetime of an application. They could be read only once and copied from static variables to the actual instance variables on demand. &lt;/li&gt;    &lt;li&gt;LogEntry: The native and managed thread id is fetched on demand which could be too late if the output destination does asynchronous operations (queuing?). &lt;/li&gt;    &lt;li&gt;Formatters: There is no progress in the &lt;a href="http://geekswithblogs.net/akraus1/archive/2008/01/14/118543.aspx"&gt;text formatter performance&lt;/a&gt;. That is surprising to say the least since delayed LogEntry variable expansion does not help much if you use a TextFormatter with the default template to format your LogEntry. I whish so much I could check out the sources for TextFormatter ....&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h4&gt;&lt;strong&gt;The Good/The Whishes/The Summary for Entlib 4&lt;/strong&gt;&lt;/h4&gt;  &lt;p&gt;Good:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Many new features (central configuration, unity integration, ...) &lt;/li&gt;    &lt;li&gt;Performance Improvements&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Wishes&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;High quality community extensions should be included in the main code base.&lt;/li&gt;    &lt;li&gt;Do NOT Authenticode sign the strong named binaries again. I really hate the 15s &lt;a href="http://blogs.msdn.com/shawnfa/archive/2005/12/13/502779.aspx"&gt;startup delays&lt;/a&gt; of non Internet connected machines! Yes I know with .NET 3.5 there is a way to &lt;a href="http://msdn2.microsoft.com/en-us/library/bb629393.aspx"&gt;turn Authenticode verification off&lt;/a&gt; in the App.config file but .NET 2.0 users will suffer from this.&lt;/li&gt;    &lt;li&gt;Do include the pdb's for Release and Debug for all shipped binaries (ObjectBuilder too). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The next release of the Enterprise Library does deliver cool features such as Unity and support for group policy based configuration. Finally the Patterns &amp;amp; Practices team has found the time to fix some minor quirks which have been annoying but not mission critical. Since the new release seems to be API compatible with the previous versions you should definitely consider to upgrade as soon as possible. Have a look at the blog of &lt;a href="http://blogs.msdn.com/agile/default.aspx"&gt;Grigori Melnik&lt;/a&gt; for latest announcements about the upcoming release of Entlib 4.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121148"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121148" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/akraus1/aggbug/121148.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Alois Kraus</dc:creator>
            <guid>http://geekswithblogs.net/akraus1/archive/2008/04/09/121148.aspx</guid>
            <pubDate>Thu, 10 Apr 2008 01:20:17 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/akraus1/comments/121148.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/akraus1/archive/2008/04/09/121148.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/akraus1/comments/commentRss/121148.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/akraus1/services/trackbacks/121148.aspx</trackback:ping>
        </item>
        <item>
            <title>Try/Finally Pattern - Take a different path when an exception has occurred.</title>
            <link>http://geekswithblogs.net/akraus1/archive/2008/04/08/121121.aspx</link>
            <description>&lt;p&gt;Error handling is a difficult beast. And there is always one more way to do it. &lt;a href="http://blogs.msdn.com/thottams/archive/2008/03/24/handling-throwing-exceptions-and-clean-up-on-error.aspx"&gt;Thottam Sriram&lt;/a&gt; did write some nice examples what main cases you usually have to deal with. The most ugly case is the one where you cannot handle an exception but you need to do different cleanup logic in a finally block.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;               &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Func()&lt;/p&gt;  &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;   &lt;p style="margin: 0px"&gt;        {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;bool&lt;/span&gt; cleanup = &lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;try&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                OtherFunc();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                cleanup = &lt;span style="color: blue"&gt;false&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;catch&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt;)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                &lt;span style="color: green"&gt;// perform Cleanup on error&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;finally&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;if&lt;/span&gt; (cleanup)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                    &lt;span style="color: green"&gt;// perform cleanup on error&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        }&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt; &lt;/div&gt; The necessity to keep a state variable for a corner case does complicate the code quite a lot. You can get around that by knowing that .NET exceptions just wrap &lt;a href="http://www.codeproject.com/KB/cpp/exceptionhandler.aspx"&gt;SEH (Structured Exception Handling)&lt;/a&gt; of Windows. The CLR does make extensive usage of SEH which you can read in the wonderful article from &lt;a href="http://blogs.msdn.com/cbrumme/archive/2003/10/01/51524.aspx"&gt;Chris Brumme&lt;/a&gt;. To sum it up in a few words if an exception is thrown an &lt;a href="http://msdn2.microsoft.com/en-us/library/ms679331(VS.85).aspx"&gt;Exception Pointers&lt;/a&gt; structure is allocated. The actual exception processing is done two in two steps.   &lt;p&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div style="margin: 0px"&gt;Ask all exception handlers what about the current error can be done. If one says it can fix it the exception processing is stopped. No exception will ever happen.&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div style="margin: 0px"&gt;If no handler could fix it in the first pass they are actually invoked one by one and the stack unwinding does start.&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p style="margin: 0px"&gt;C++ has special keywords for SEH named &lt;a href="http://msdn2.microsoft.com/en-us/library/s58ftw19(VS.80).aspx"&gt;__try/__except/__leave&lt;/a&gt; which cannot be mixed with the regular try/finally C++ keywords within one function because only one exception handling chain within a function does make sense. Now you could ask how that complicated stuff can make by error handling easier? Well since we know that during an exception unwind scenario for the executing thread an Exception Pointers structure must exist we can check for its existence and we can distinguish the non exception case from the other. The BCL gives us direct access to this precious information via &lt;a href="http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getexceptionpointers.aspx"&gt;Marshal.GetExceptionPointers&lt;/a&gt;. Armed with that knowledge we can create a simple helper class that returns true if we are in an exception unwind case.&lt;/p&gt;  &lt;p style="margin: 0px"&gt; &lt;/p&gt;  &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;   &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ExceptionHelper&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;    {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Check if we are in a exception unwind scenario or not.&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; InException&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;get&lt;/span&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;            {&lt;font color="#ff0000"&gt;   // Errata: The red marked code seems to be necessary. Since unit tests with .NET 2.0 &lt;/font&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;font color="#ff0000"&gt;                // have shown that only checking for the Exception Pointers structure does not always work.&lt;/font&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.GetExceptionPointers() == &lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;.Zero &amp;amp;&amp;amp;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                       &lt;font color="#ff0000"&gt;Marshal.GetExceptionCode() == 0&lt;/font&gt; ? &lt;span style="color: blue"&gt;false&lt;/span&gt; : &lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;    }&lt;/p&gt; &lt;/div&gt;  &lt;p style="margin: 0px"&gt; &lt;/p&gt;  &lt;p style="margin: 0px"&gt;The code from above becomes now&lt;/p&gt;  &lt;p style="margin: 0px"&gt; &lt;/p&gt;  &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;   &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; ImprovedFunc()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;try&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                OtherFunc();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;finally&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;ExceptionHelper&lt;/span&gt;.InException)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                    &lt;span style="color: green"&gt;// perform cleanup on error&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;else&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                    &lt;span style="color: green"&gt;// Do normal cleanup in non exception case&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        }&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;/p&gt; &lt;/div&gt; We did get rid of the catch clause and the state variable. That little trick can make your life easier in some situations. You can call the check property not only in a finally clause but also from a helper function because the Exception Pointers structure is thread local and visible as long exception processing is going on.   &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0px"&gt; &lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Remarks&lt;/strong&gt;&lt;/h3&gt;  &lt;p style="margin: 0px"&gt; &lt;/p&gt;  &lt;p style="margin: 0px"&gt;At CLR IL (Intermediate Language) level there is the fault keyword which is similar. It acts like a finally block that is only executed when an exception has occurred. Besides the fact that C# does not support it is not really something that I would want. When an error happens I must execute nearly the same cleanup actions as in the non exceptional case. For that reason code sharing within one code block is essential to prevent code duplication both handlers. If you try to be smart and use the goto keyword (yes I won't dare to use it if it would have worked) to jump from a from a catch handler into the finally handler to skip a portion of the cleanup code you will get a compile error.&lt;/p&gt;  &lt;p style="margin: 0px"&gt;Since we have got our hands on the Exception Pointers structure we should be able to find there some reference to the managed exception and perhaps even return it. I tried that and failed. By looking at the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=8C09FD61-3F26-4555-AE17-3121B4F51D4D&amp;amp;displaylang=en"&gt;Rotor source code&lt;/a&gt; I could not find evidence that this structure does contain any hints to the managed exception object. It looks like that the managed Thread implementation has it stored somewhere but since CLR objects are a mixture of IL code and C++ classes it is not feasible to use a simple fixed offset and cast it to the managed exception object.&lt;/p&gt;  &lt;p style="margin: 0px"&gt;If somebody has more info about that I am always interested to learn more ...&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121121"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121121" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/akraus1/aggbug/121121.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Alois Kraus</dc:creator>
            <guid>http://geekswithblogs.net/akraus1/archive/2008/04/08/121121.aspx</guid>
            <pubDate>Tue, 08 Apr 2008 23:37:42 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/akraus1/comments/121121.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/akraus1/archive/2008/04/08/121121.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/akraus1/comments/commentRss/121121.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/akraus1/services/trackbacks/121121.aspx</trackback:ping>
        </item>
        <item>
            <title>Really Fast Formatting with Enterprise Library</title>
            <category>Performance</category>
            <link>http://geekswithblogs.net/akraus1/archive/2008/01/14/118543.aspx</link>
            <description>&lt;p&gt;One of the action points for &lt;a href="http://www.codeplex.com/entlib/Wiki/View.aspx?title=EntLib4%20Backlog&amp;amp;referringTitle=Home"&gt;Enterprise Library 4&lt;/a&gt; is to improve the performance of the TextFormatter. I like performance problems and found some interesting results I would like to share here. TextFormatter does take a template where the placeholders are expanded for every log message. The template does look like this&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#ff8000"&gt;Timestamp:&lt;/font&gt; {timestamp} &lt;br /&gt;
&lt;font color="#ff8040"&gt;Message:&lt;/font&gt; {message} &lt;br /&gt;
&lt;font color="#ff8000"&gt;Category:&lt;/font&gt; {category} &lt;br /&gt;
&lt;font color="#ff8000"&gt;Priority:&lt;/font&gt; {priority} &lt;br /&gt;
&lt;font color="#ff8000"&gt;EventId:&lt;/font&gt; {eventid} &lt;br /&gt;
&lt;font color="#ff8000"&gt;Severity:&lt;/font&gt; {severity} &lt;br /&gt;
&lt;font color="#ff8000"&gt;Title:&lt;/font&gt;{title} &lt;br /&gt;
&lt;font color="#ff8000"&gt;Machine: &lt;/font&gt;{machine} &lt;br /&gt;
&lt;font color="#ff8000"&gt;Application Domain: &lt;/font&gt;{appDomain} &lt;br /&gt;
&lt;font color="#ff8000"&gt;Process Id:&lt;/font&gt; {processId} &lt;br /&gt;
&lt;font color="#ff8000"&gt;Process Name:&lt;/font&gt; {processName} &lt;br /&gt;
&lt;font color="#ff8000"&gt;Win32 Thread Id:&lt;/font&gt; {win32ThreadId} &lt;br /&gt;
&lt;font color="#ff8000"&gt;Thread Name:&lt;/font&gt; {threadName} &lt;br /&gt;
&lt;font color="#ff8000"&gt;Extended Properties:&lt;/font&gt; {dictionary({key} - {value} &lt;br /&gt;
)}&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;TextFormatter does use StringBuilder to create from the template a mutable string and does then call StringBuilder.Replace for each token it could contain. It does basically a String.IndexOf to find if something has to be replaced and then allocates a new string which contains enough space for the token to be inserted. This process is repeated until all gaps are filled. This results in searches for tokens which are not present in the current template and some memory allocation/copy overhead because the string to replace will never have the same size.&lt;/p&gt;
&lt;p&gt;But the most expensive things are the TokenFunctions which do expand e.g. the Extended Properties collection at the end of the example template. A quick look into the source shows where the problem is:&lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;virtual&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Format(StringBuilder messageBuilder, LogEntry log)&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;p style="MARGIN: 0px"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;       ...&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; messageString = &lt;strong&gt;messageBuilder.ToString();&lt;/strong&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;strong&gt;       ...&lt;/strong&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The performance optimization to use StringBuilder in the Formatter has cornered the TokenFunction formatter because it cannot to a simple replace of a fixed string and needs to parse the template. But StringBuilder gives you no access to the not yet constructed string and you need to use therefore this solution.&lt;/p&gt;
&lt;p&gt;Armed with this knowledge I came up with an alternate approach to format a text template which does not suffer from the deficiencies of StringBuilder.Replace. The trick is to simply use StringBuilder.Append. To be able to do this I split the template apart in its constant (marked in orange) parts and use for each dynamic content a retriever function. The tuple (string, callback) is put into an object (MicroFormatter) from which we can create a list that allows us to build up the expanded template step by step.  Registering template fill callbacks does eliminate all string searches and (nearly) all buffer reallocations. The cool thing is that this is also possible for the TokenFunctions which can now directly format the parsed template.&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; MicroFormatter&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; Constant prefix which is part of the message template&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Prefix { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; Gets the dynamic content of the LogEntry&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Func&amp;lt;LogEntry, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&amp;gt; Retriever { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; TokenFunction formatter wrapper function which does need a string template as parameter which is then formatted.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; The formatted string is then returned&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Func&amp;lt;LogEntry, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&amp;gt; TokenFuncRetriever { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; Template which is expanded by the token e.g. "dictionary({key} - {value}" for the DictionaryFormatter&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; TokenFuncTemplate { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; MicroFormatter()&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; MicroFormatter(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; prefix, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; tokenFuncTemplate, Func&amp;lt;LogEntry, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&amp;gt; tokenFuncRetriver)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            Prefix = prefix;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            TokenFuncTemplate = tokenFuncTemplate;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            TokenFuncRetriever = tokenFuncRetriver;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; MicroFormatter(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; prefix, Func&amp;lt;LogEntry, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&amp;gt; retriever)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            Prefix = prefix;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            Retriever = retriever;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; Appends to a StringBuilder instance the static and dynamic contents of the parsed template&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: gray"&gt;&lt;/span&gt;&lt;/p&gt;
           &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Format(LogEntry entry, StringBuilder template)
&lt;p&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (Prefix != &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) &lt;span style="COLOR: green"&gt;// Append constant template part&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                &lt;font color="#ff0000"&gt;template.Append(Prefix);&lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (Retriever != &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) &lt;span style="COLOR: green"&gt;// Add dynamic content of LogEntry&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                &lt;font color="#ff0000"&gt;template.Append(Retriever(entry));&lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;else&lt;/span&gt; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (TokenFuncRetriever != &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) &lt;span style="COLOR: green"&gt;// Or add dynamic content of TokenFunction&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                &lt;font color="#ff0000"&gt;template.Append(TokenFuncRetriever(entry, TokenFuncTemplate));&lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;This allows us to generate a easy Format Method:&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;p style="MARGIN: 0px"&gt;    &lt;span style="COLOR: green"&gt;// Combined list of microformatters which allow an easy StringBuilder.Append instead of&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    &lt;span style="COLOR: green"&gt;// a much slower StringBuilder.Replace which does first search (many times pointless) and&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    &lt;span style="COLOR: green"&gt;// then replaces the string which needs to reallocate and copy the buffer&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    List&amp;lt;MicroFormatter&amp;gt; myFormatters = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; List&amp;lt;MicroFormatter&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Format(LogEntry entry)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: green"&gt;// allocate string builder can be dynamically sized&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        StringBuilder sb = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; StringBuilder(500);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: green"&gt;// Call formatters in sequence they were entered to build the spitted&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: green"&gt;// template piece by piece together again.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (MicroFormatter fmt &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; myFormatters)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;           &lt;font color="#ff0000"&gt;fmt.Format(entry, sb);&lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; sb.ToString();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;The red lines are the important changes which give us much better performance. This simple solution does improve the formatting speed over 14 times! That should be enough for everyone ;-) Another costly part is the creation of the LogEntry itself which does call a private method in its default ctor (CollectIntrinsicProperties) which can cost quite some time. It would be nice if the P&amp;amp;P team would make this function virtual so one has a chance to optimize things a bit. This would be beneficial if somebody does want to filter LogEntry derived objects which can be filtered out without needing any of the other properties. That would allow to defer the costly data collection when it is really ensured that the entry will be logged.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;Performance&lt;/h3&gt;
&lt;p&gt;All Performance Tests were performed with an Intel Core Duo 6600 @ 2.40 GHz with 3 GB RAM, EntLib 3.1, VS2008 RTM and the message template which is shown at the start of the article.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table cellspacing="0" cellpadding="2" width="556" border="0"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign="top" width="224"&gt;&lt;strong&gt;Test Case (executed 100K times)&lt;/strong&gt;&lt;/td&gt;
            &lt;td valign="top" width="185"&gt;&lt;strong&gt;Execution Frequency in 1/s&lt;/strong&gt;&lt;/td&gt;
            &lt;td valign="top" width="143"&gt;Speed Gain (x factor)&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="top" width="223"&gt;Create LogEntry&lt;/td&gt;
            &lt;td valign="top" width="185"&gt;   22 000 &lt;/td&gt;
            &lt;td valign="top" width="143"&gt;-&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="top" width="222"&gt;Format LogEntry TextFormatter&lt;/td&gt;
            &lt;td valign="top" width="185"&gt;    5 300&lt;/td&gt;
            &lt;td valign="top" width="143"&gt;1&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="top" width="221"&gt;Format LogEntry SmartFormatter&lt;/td&gt;
            &lt;td valign="top" width="185"&gt;  75 000&lt;/td&gt;
            &lt;td valign="top" width="143"&gt;14&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;More Code&lt;/h3&gt;
&lt;p&gt;The complete code of my SmartFormatter is shown below:&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;namespace&lt;/span&gt; Logging&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;{&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; Really fast formatter with equivalent features as TextFormatter of the Enterprise Library&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; SmartFormatter : ILogFormatter&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;char&lt;/span&gt; TokenStartChar = &lt;span style="COLOR: #a31515"&gt;'{'&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; timeStampToken = &lt;span style="COLOR: #a31515"&gt;"{timestamp}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; messageToken = &lt;span style="COLOR: #a31515"&gt;"{message}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; categoryToken = &lt;span style="COLOR: #a31515"&gt;"{category}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; priorityToken = &lt;span style="COLOR: #a31515"&gt;"{priority}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; eventIdToken = &lt;span style="COLOR: #a31515"&gt;"{eventid}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; severityToken = &lt;span style="COLOR: #a31515"&gt;"{severity}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; titleToken = &lt;span style="COLOR: #a31515"&gt;"{title}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; errorMessagesToke = &lt;span style="COLOR: #a31515"&gt;"{errorMessages}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; machineToken = &lt;span style="COLOR: #a31515"&gt;"{machine}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; appDomainNameToken = &lt;span style="COLOR: #a31515"&gt;"{appDomain}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; processIdToken = &lt;span style="COLOR: #a31515"&gt;"{processId}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; processNameToken = &lt;span style="COLOR: #a31515"&gt;"{processName}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; threadNameToken = &lt;span style="COLOR: #a31515"&gt;"{threadName}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; win32ThreadIdToken = &lt;span style="COLOR: #a31515"&gt;"{win32ThreadId}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; activityidToken = &lt;span style="COLOR: #a31515"&gt;"{activity}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; NewLineToken = &lt;span style="COLOR: #a31515"&gt;"{newline}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; TabToken = &lt;span style="COLOR: #a31515"&gt;"{tab}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; DictionaryStartToken = &lt;span style="COLOR: #a31515"&gt;"{dictionary("&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; KeyValueStartToken = &lt;span style="COLOR: #a31515"&gt;"{keyvalue("&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; TimeStampStartToken = &lt;span style="COLOR: #a31515"&gt;"{timestamp("&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; ReflectedPropertyStartToken = &lt;span style="COLOR: #a31515"&gt;"{property("&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;const&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; EndToken = &lt;span style="COLOR: #a31515"&gt;")}"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; Key is the Token template e.g. "{timestamp}" and value is a callback function that retrieves the requested string from&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; a LogEntry object.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, Func&amp;lt;LogEntry, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&amp;gt;&amp;gt; myTokenToFunc = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, Func&amp;lt;LogEntry, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; Key is the Token Function start e.g. "{dictionary(" and value is a callback function that formats from a&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; configured template the contents of a LogEntry object.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, Func&amp;lt;LogEntry, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&amp;gt;&amp;gt; myTokenFormatterToFunc = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, Func&amp;lt;LogEntry, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: green"&gt;// Combined list of MicroFormatters which allow an easy StringBuilder.Append instead of&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: green"&gt;// a much slower StringBuilder.Replace which does first search (many times pointless) and&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: green"&gt;// then replaces the string which needs to reallocate and copy the buffer&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;MicroFormatter&amp;gt; myFormatters = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;MicroFormatter&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; For brevity we use the C# 3.0 lambda syntax&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;virtual&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; AddWellknownTokens()&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(timeStampToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.TimeStampString; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(messageToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.Message; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(categoryToken, FormatCategoriesCollection);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(priorityToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.Priority.ToString(); });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(eventIdToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.EventId.ToString(); });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(severityToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.Severity.ToString(); });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(titleToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.Title; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(errorMessagesToke, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.ErrorMessages; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(machineToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.MachineName; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(appDomainNameToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.AppDomainName; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(processIdToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.ProcessId; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(processNameToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.ProcessName; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(threadNameToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.ManagedThreadName; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(win32ThreadIdToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.Win32ThreadId; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(activityidToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ent.ActivityId.ToString(); });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(NewLineToken, (LogEntry ent) =&amp;gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Environment&lt;/span&gt;.NewLine; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenToFunc.Add(TabToken, (LogEntry ent) =&amp;gt; {&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: #a31515"&gt;"\t"&lt;/span&gt;; });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: green"&gt;// register token functions&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenFormatterToFunc.Add(DictionaryStartToken, (LogEntry ent, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; template) =&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                DictionaryToken token = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; DictionaryToken();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; token.FormatToken(template, ent);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenFormatterToFunc.Add(KeyValueStartToken, (LogEntry ent, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; template) =&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    KeyValueToken token = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; KeyValueToken();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; token.FormatToken(template, ent);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenFormatterToFunc.Add(TimeStampStartToken, (LogEntry ent, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; template) =&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    TimeStampToken token = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; TimeStampToken();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; token.FormatToken(template, ent);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            myTokenFormatterToFunc.Add(ReflectedPropertyStartToken, (LogEntry ent, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; template) =&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    ReflectedPropertyToken token = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; ReflectedPropertyToken();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; token.FormatToken(template, ent);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                });&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; SmartFormatter()&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {}&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; SmartFormatter(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; template)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            AddWellknownTokens();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            BuildFormatterList(template);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Format(LogEntry entry)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: green"&gt;// allocate string builder can be dynamically sized&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: #2b91af"&gt;StringBuilder&lt;/span&gt; sb = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;StringBuilder&lt;/span&gt;(500);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: green"&gt;// Call formatters in sequence they were entered to build the splitted&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: green"&gt;// template piece by piece together again.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (MicroFormatter fmt &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; myFormatters)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                fmt.Format(entry, sb);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; sb.ToString();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; Returns the template in between the parentheses for a token function.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; Expecting tokens in this format: {keyvalue(myKey1)}.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;param name="startPos"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;Start index to search for the next token function.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;param name="message"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;Message template containing tokens.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;Inner template of the function.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;virtual&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; GetInnerTemplate(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; tokenFuncStart, &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; startPos, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; message)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; tokenStartPos = message.IndexOf(tokenFuncStart, startPos) + tokenFuncStart.Length;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; endPos = message.IndexOf(EndToken, tokenStartPos);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; message.Substring(tokenStartPos, endPos - tokenStartPos);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; Parse the template and create the list of microformatters. This way we get an ordered list&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; of things we really have to do instead of trying to blindly format tokens in a template which&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; may not be present&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: gray"&gt;///&lt;/span&gt;&lt;span style="COLOR: green"&gt; &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;param name="template"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;virtual&lt;/span&gt; &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; BuildFormatterList(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; template)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            MicroFormatter fmt = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; MicroFormatter();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;char&lt;/span&gt;&amp;gt; curNonTokenString = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;char&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; isTokenChar = &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: green"&gt;// Go through template and build list of Microformatters&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;for&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; i = 0; i&amp;lt;template.Length; i++)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                isTokenChar = &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (template[i] == TokenStartChar)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    &lt;span style="COLOR: green"&gt;// Transform all template variables &lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; token &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; myTokenToFunc.Keys)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                        &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (template.IndexOf(token, i) == i)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            i += token.Length-1;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            MicroFormatter formatter = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; MicroFormatter();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            formatter.Prefix = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;(curNonTokenString.ToArray());&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            &lt;span style="COLOR: green"&gt;// Get for this token the callback function which retrieves&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            &lt;span style="COLOR: green"&gt;// from a LogEntry object the resulting dynamic string&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            formatter.Retriever = myTokenToFunc[token];&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            myFormatters.Add(formatter);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            isTokenChar = &lt;span style="COLOR: blue"&gt;true&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            curNonTokenString.Clear();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            &lt;span style="COLOR: blue"&gt;break&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    &lt;span style="COLOR: green"&gt;// Transform all Token functions in the message template&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; tokenStart &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; myTokenFormatterToFunc.Keys)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                        &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (template.IndexOf(tokenStart, i) == i)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; tokenTemplate = GetInnerTemplate(tokenStart,i, template);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            i += tokenStart.Length + tokenTemplate.Length + EndToken.Length - 1;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            &lt;span style="COLOR: green"&gt;// Create formatter for this token function and store the token function&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            &lt;span style="COLOR: green"&gt;// template inside the formatter&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            MicroFormatter formatter = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; MicroFormatter(&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;(curNonTokenString.ToArray()),&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                                                                          tokenTemplate, &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                                                                          myTokenFormatterToFunc[tokenStart]);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            myFormatters.Add(formatter);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            isTokenChar = &lt;span style="COLOR: blue"&gt;true&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            curNonTokenString.Clear();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                            &lt;span style="COLOR: blue"&gt;break&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                &lt;span style="COLOR: green"&gt;// if the current template character does not belong to a token variable or function&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                &lt;span style="COLOR: green"&gt;// store it later as constant template part in the next MicroFormatter instance&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!isTokenChar)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    curNonTokenString.Add(template[i]);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: green"&gt;// the rest of the template is constant&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (curNonTokenString.Count != 0)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                myFormatters.Add( &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; MicroFormatter(&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;(curNonTokenString.ToArray()), &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) );&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; FormatCategoriesCollection(LogEntry ent)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: #2b91af"&gt;StringBuilder&lt;/span&gt; categoriesListBuilder = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;StringBuilder&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; i = 0;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;String&lt;/span&gt; category &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; ent.Categories)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                categoriesListBuilder.Append(category);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (++i &amp;lt; ent.Categories.Count)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                    categoriesListBuilder.Append(&lt;span style="COLOR: #a31515"&gt;", "&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; categoriesListBuilder.ToString();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;   }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;}&lt;/p&gt;
&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=118543"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=118543" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/akraus1/aggbug/118543.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Alois Kraus</dc:creator>
            <guid>http://geekswithblogs.net/akraus1/archive/2008/01/14/118543.aspx</guid>
            <pubDate>Tue, 15 Jan 2008 00:18:46 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/akraus1/comments/118543.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/akraus1/archive/2008/01/14/118543.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/akraus1/comments/commentRss/118543.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/akraus1/services/trackbacks/118543.aspx</trackback:ping>
        </item>
        <item>
            <title>Visual Studio VS2008 Is Out!</title>
            <link>http://geekswithblogs.net/akraus1/archive/2007/11/20/117011.aspx</link>
            <description>&lt;p&gt;This is my first test post with Windows Live Writer 2008. I hope it will not mess up when I paste source code ....&lt;/p&gt;
&lt;p&gt;But back to business. VS2008 formerly known as Orcas is out! It is just great and has many cool features inside it. &lt;/p&gt;
&lt;p&gt;You can download various editions of Visual Studio 2008 at the following &lt;a href="http://blogs.msdn.com/astebner/archive/2007/11/19/6405795.aspx"&gt;locations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One of the best features are Language Integrated Queries (LINQ). The first question that does arise is if LINQ to Objects is able to replace common for loops in terms of performance in every case. To check it out I did write a very simple test where we filter for specific items in an array and return the filtered list.&lt;/p&gt;
&lt;p&gt;List&amp;lt;string&amp;gt; Test = new List&amp;lt;string&amp;gt; { "This", "is", "a", "list", "that", "will", "be", "filtered", "with", &lt;br /&gt;
"a", "for", "loop", "and", "LINQ"}; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;List&amp;lt;string&amp;gt; FilterFor(string substr) &lt;br /&gt;
{ &lt;br /&gt;
     List&amp;lt;string&amp;gt; ret = new List&amp;lt;string&amp;gt;(); &lt;/p&gt;
&lt;p&gt;     foreach (string str in Test) &lt;br /&gt;
     { &lt;br /&gt;
         if (str.Contains(substr)) &lt;br /&gt;
             ret.Add(str); &lt;br /&gt;
     } &lt;/p&gt;
&lt;p&gt;     return ret; &lt;br /&gt;
} &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;List&amp;lt;string&amp;gt; FilterForLinq(string substr) &lt;br /&gt;
{ &lt;br /&gt;
     var ret = from str in Test where str.Contains(substr) select str; &lt;br /&gt;
     return ret.ToList&amp;lt;string&amp;gt;(); &lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;On my Intel Core Duo 6600 @ 2.40 GHz with 3 GB RAM I get&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="2" width="437" border="1"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign="top" width="216"&gt; &lt;/td&gt;
            &lt;td valign="top" width="109"&gt;First Call in ms&lt;/td&gt;
            &lt;td valign="top" width="110"&gt;Tight Loop in Calls/ms&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="top" width="215"&gt;FilterFor&lt;/td&gt;
            &lt;td valign="top" width="109"&gt;1&lt;/td&gt;
            &lt;td valign="top" width="111"&gt;584&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="top" width="215"&gt;FilterForLinq&lt;/td&gt;
            &lt;td valign="top" width="108"&gt;2&lt;/td&gt;
            &lt;td valign="top" width="112"&gt;454&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="top" width="214"&gt;FilterForLinq with IEnumerable&amp;lt;string&amp;gt; as return value&lt;/td&gt;
            &lt;td valign="top" width="108"&gt;1&lt;/td&gt;
            &lt;td valign="top" width="113"&gt;17543&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;The values were measured with the .NET Framework 3.5 RTM in release configuration. It seems that for simple filters we see a small (20%) speed loss if we use LINQ in very tight loops. But when I used a profiler (ANTS 3.0) I did get no speed difference. Since the profiler uses callbacks to get the exact timing we loose data locality and CPU cache benefits which slows the program nearly 100 times down such small effects are not visible anymore.&lt;/p&gt;
&lt;p&gt;When we do only create the query but do not execute it we are over 30 times faster than the traditional array based approach. Lazy evaluation is the key to defer the actual work if we do not need all values or do not use them always. Huge speed gains are possible by doing only as much work as need but no more. I am looking forward to &lt;a href="http://msdn.microsoft.com/msdnmag/issues/07/10/PLINQ/Default.aspx?loc=en"&gt;PLINQ&lt;/a&gt; which could take advantage of my two CPUs.&lt;/p&gt;
&lt;p&gt;If you want to get started with more complex queries I recommend the &lt;a href="http://msdn2.microsoft.com/en-us/vcsharp/aa336746.aspx"&gt;101 LINQ Samples&lt;/a&gt; site to learn what you can do with such queries or &lt;a href="http://msdn2.microsoft.com/de-de/netframework/aa904594.aspx"&gt;MSDN&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=117011"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=117011" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/akraus1/aggbug/117011.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Alois Kraus</dc:creator>
            <guid>http://geekswithblogs.net/akraus1/archive/2007/11/20/117011.aspx</guid>
            <pubDate>Wed, 21 Nov 2007 01:27:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/akraus1/comments/117011.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/akraus1/archive/2007/11/20/117011.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/akraus1/comments/commentRss/117011.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/akraus1/services/trackbacks/117011.aspx</trackback:ping>
        </item>
        <item>
            <title>Best Practices Not Followed - Zune Player And A German Windows XP</title>
            <link>http://geekswithblogs.net/akraus1/archive/2007/02/20/106735.aspx</link>
            <description>&lt;p&gt;Today I got my brand new Zune MP3 player which I did win at a Microsoft Event. Lucky me ;-). Ok install the software and you are ready to rockn roll, I thought, and I was wrong. Very wrong. At&amp;nbsp;94%&amp;nbsp;of the installation it did stop with an error which was there&amp;nbsp;even after a reboot. A quick Google search did confirm that other users had this problem also. One of the possible installation problems was the the Users group has&amp;nbsp;the wrong name. Aha! I have a German Windows XP where the Users group is named Benutzer. The solution was to simply fire up the user management snapin and rename the Benutzer group to User. But wait I do not have installed a Home Edition of Windows XP. Darn there is no usable User Management Snapin installed. This was especially annoying since I did program a user and group management MMC snapin for my employer several years ago. I do even know the API calls. After trying around with WMI and DirectoryEntry, WindowsIdentity under Powershell, C# and VB Script I gave up and decided that there must be a simpler solution. And there was. The net command of Windows does allow you to programmatically manage groups and users. No rename there but it should be enough to create a Users group and assign it to my user account.&lt;/p&gt; &lt;p&gt;I add the description in German so others have the chance to find this information with Google/Another MS approved search engine.&lt;/p&gt; &lt;p&gt;Kann Zune Player nicht mit deutschem Windows XP installieren. Die Installation stoppt bei 94%. Um den Fehler zu beheben bitte folgende Befehle auf einem DOS command Prompt eingeben. Der String YourUserName mit dem aktuellen Benutzer Namen ersetzen. Danach sollte die Zune Player installation fehlerfrei funktionieren.&lt;/p&gt; &lt;p&gt;&lt;em&gt;net localgroup "Users" /ADD&lt;br&gt;net localgroup "Users" "YourUserName" /ADD &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;net localgroup "INTERACTIVE" /ADD&lt;br&gt;net localgroup "INTERACTIVE" "YourUserName" /ADD&lt;/em&gt;  &lt;p&gt;This will fix the error which do show up in the Windows Application Event Log.  &lt;p&gt;&lt;em&gt;An error occurred while applying security settings. Users is not a valid user or group. This could be a problem with the package, or a problem connecting to a domain controller on the network. Check your network connection and click Retry, or Cancel to end the install. Unable to locate the user's SID, system error 1332; (NULL); (NULL); (NULL).&lt;/em&gt;  &lt;p&gt;&lt;em&gt;Zune -- Error 1609. An error occurred while applying security settings. INTERACTIVE is not a valid user or group. This could be a problem with the package, or a problem connecting to a domain controller on the network. Check your network connection and click Retry, or Cancel to end the install. Unable to locate the user's SID, system error 1332; (NULL); (NULL); (NULL).&lt;/em&gt;  &lt;p&gt;What do we learn from this. Even Microsoft does not always follow its own security programming best practices. The Users and Interactive groups can easily be retrieved via it's well known SIDs (Security Identifiers) and not by their localized names. For my vigilant Microsoft Employee readers I paste them here so they can fix this issue faster ;-). &lt;p&gt;&lt;em&gt;SID: S-1-5-32-545&lt;br&gt;Name: Users&lt;br&gt;Description: A built-in group. After the initial installation of the operating system, the only member is the Authenticated Users group. When a computer joins a domain, the Domain Users group is added to the Users group on the computer.&lt;/em&gt;  &lt;p&gt;&lt;em&gt;SID: S-1-5-4&lt;br&gt;Name: Interactive&lt;br&gt;Description: A group that includes all users that have logged on interactively. Membership is controlled by the operating system.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;I cannot tell you how good this player is compared to my IPod Nano which I incidentally did win also (no it was not an Apple event).&amp;nbsp;It does still sync&amp;nbsp;my MP3 folders which it managed to find somehow. What I do not like is that it does not show up as new drive where I can simply copy the files onto. This might be a tribute to DRM which will hopefully become history in the not so distant future.&lt;/p&gt; &lt;p&gt;Funny side note: At the back of my Zune are greetings from Seattle. &lt;/p&gt; &lt;p&gt;&lt;img height="380" src="http://geekswithblogs.net/images/geekswithblogs_net/akraus1/6246/o_Zune-Back.jpg" width="600"&gt;&lt;/p&gt; &lt;p&gt;Hello From Erlangen ;-)&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=106735"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=106735" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/akraus1/aggbug/106735.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Alois Kraus</dc:creator>
            <guid>http://geekswithblogs.net/akraus1/archive/2007/02/20/106735.aspx</guid>
            <pubDate>Tue, 20 Feb 2007 12:50:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/akraus1/comments/106735.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/akraus1/archive/2007/02/20/106735.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/akraus1/comments/commentRss/106735.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/akraus1/services/trackbacks/106735.aspx</trackback:ping>
        </item>
        <item>
            <title>Create Strong Named Assemblies - The Easy Way</title>
            <category>General C# Programming</category>
            <link>http://geekswithblogs.net/akraus1/archive/2007/01/23/104288.aspx</link>
            <description>Strong naming has always been a complicated matter.&amp;nbsp; Sometimes it is even impossible when you get unsigned assemblies from a third party software vendor and you have to build strong named assemblies to install them into the GAC. When you decide to strong name your project it is a all or nothing decision. If your target is strong named then all&amp;nbsp;references must also be strong named. If you do not have the source code and a project for your third party dll you will not be able to sign your project. I have created&amp;nbsp;&lt;A href="http://www.codeplex.com/Signer/Release/ProjectReleases.aspx"&gt;Signer&lt;/A&gt; which is hosted at CodePlex that allows you to add strong names to binaries within minutes. You can even create a strong named build of your whole project without any changes to your build settings. Below is a picture which shows Signer in action:&lt;BR&gt;&lt;BR&gt;&lt;IMG title=Signer style="WIDTH: 989px; HEIGHT: 559px" alt=Signer src="/images/geekswithblogs_net/akraus1/3938/o_Signer.JPG"&gt;&lt;BR&gt;&lt;BR&gt;
&lt;H2&gt;How does it work?&lt;/H2&gt;Signer does basically a full round trip by decompiling the assembly into IL code make the necessary modifications and compile it back to a valid assembly. The required modifications include&lt;BR&gt;
&lt;UL&gt;
&lt;LI&gt;Update of all references&lt;/LI&gt;
&lt;LI&gt;Change/Removal of InternalsVisibleToAttribute&lt;/LI&gt;
&lt;LI&gt;Update of custom attributes with a type parameter&lt;/LI&gt;
&lt;LI&gt;A little fix to work around an ILDASM problem&lt;/LI&gt;&lt;/UL&gt;&lt;SPAN style="FONT-WEIGHT: bold"&gt;Reference Update in IL&lt;BR&gt;&lt;/SPAN&gt;&lt;BR&gt;This is the easy part. A reference does consist of the assembly name, public key token and it's version. Signer has only to insert the public key token where none is present to patch the IL file.&lt;BR&gt;&lt;BR&gt;&lt;SMALL&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;.assembly extern Microsoft.Practices.EnterpriseLibrary.Common&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;{&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;SPAN style="FONT-WEIGHT: bold"&gt;.publickeytoken = (BE CA 05 5E 5B 7D 2D C8 ) // Inserted by Signer if not present&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp; .ver 2:0:0:0&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;/SMALL&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;SMALL&gt;}&lt;/SMALL&gt;&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-WEIGHT: bold"&gt;InternalsVisibleTo Attribute&lt;BR&gt;&lt;/SPAN&gt;&lt;BR&gt;With .NET 2.0 the &lt;A href="http://msdn2.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx"&gt;InternalsVisibleTo&lt;/A&gt; attribute was introduced that allows to grant other assemblies access to classes and methods marked with the internal keyword. To prevent in a strong name scenario that an unsigned assembly does get access to internals directly (you can use reflection instead but this comes with a perf cost) the CLR does check at runtime if all InternalsVisibleTo attribute declarations grant access to strong named assemblies only. If not a runtime exception is thrown and the process terminates.&lt;BR&gt;&lt;BR&gt;&lt;SMALL&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;.custom&amp;nbsp; instance void [mscorlib]System.Runtime.CompilerServices.InternalsVisibleToAttribute::.ctor(string)&amp;nbsp; = &lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;( 01 00 48 4D 69 63 72 6F 73 6F 66 74 2E 50 72 61&amp;nbsp;&amp;nbsp; // ..HMicrosoft.Pra&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; 63 74 69 63 65 73 2E 45 6E 74 65 72 70 72 69 73&amp;nbsp;&amp;nbsp; // ctices.Enterpris&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 65 4C 69 62 72 61 72 79 2E 4C 6F 67 67 69 6E 67&amp;nbsp;&amp;nbsp; // eLibrary.Logging&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2E 43 6F 6E 66 69 67 75 72 61 74 69 6F 6E 2E 44&amp;nbsp;&amp;nbsp; // .Configuration.D&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 65 73 69 67 6E 2E 54 65 73 74 73 00 00 )&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // esign.Tests.."&lt;/SPAN&gt;&lt;/SMALL&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;BR&gt;You have to insert the public key which is over 300 bytes long into your project which is quite tedious if you want to do it manually. At the moment Signer makes life easy and simply removes the attribute to prevent run time errors but if needed the change is trivial. &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-WEIGHT: bold"&gt;Custom Attributes&lt;/SPAN&gt;&lt;BR&gt;This was by far the most tricky part. When you declare custom attributes with a type parameter the full qualified type name including assembly and public key token is inserted into the IL code. Normally you get this as a binary blob but with the /CAVERBAL option of ILDASM which was introduced with .NET 2.0 things get much easier.&lt;BR&gt;&lt;BR&gt;&lt;SMALL&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;.custom instance void [System]System.ComponentModel.EditorAttribute::.ctor(class [mscorlib]System.Type,&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; class [mscorlib]System.Type)&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; = {&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;type(class&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 'Microsoft.Practices.EnterpriseLibrary.Configuration.Design.ReferenceEditor,&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Microsoft.Practices.EnterpriseLibrary.Configuration.Design, Version=2.0.0.0, Culture=neutral,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PublicKeyToken=beca055e5b7d2dc8')&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;type(class &lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;'System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral,&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; PublicKeyToken=b03f5f7f11d50a3a')&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;/SMALL&gt;&lt;BR&gt;Signer does parse the attributes and does set the PublicKeyToken where needed.&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-WEIGHT: bold"&gt;ILDASM Problems&lt;/SPAN&gt;&lt;BR&gt;All would work wonderful if, well if the nice /CAVERBAL option would produce running code. But I got many ConfiguratonErrors exceptions which told me that the default value was of the wrong type. Arghhh. After digging a little deeper I found out what was going on. Suppose you have a simple configuration class for settings inside the App.Config file:&lt;BR&gt;&lt;BR&gt;
&lt;STYLE type=text/css&gt;
.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: teal; }
.cb3 { color: maroon; }
.cb4 { color: green; }
&lt;/STYLE&gt;

&lt;DIV class=cf&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;using&lt;/SPAN&gt; System;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;using&lt;/SPAN&gt; System.Collections.Generic;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;using&lt;/SPAN&gt; System.Text;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;using&lt;/SPAN&gt; System.Configuration;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;namespace&lt;/SPAN&gt; NoRoundTrip&lt;/P&gt;
&lt;P class=cl&gt;{&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;enum&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;MyValues&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; V1&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;class&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;Check&lt;/SPAN&gt; : &lt;SPAN class=cb2&gt;ConfigurationSection&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;const&lt;/SPAN&gt; &lt;SPAN class=cb1&gt;string&lt;/SPAN&gt; PropName = &lt;SPAN class=cb3&gt;"Name"&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb4&gt;// DefaultValue is a property of type object&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;SPAN class=cb2&gt;ConfigurationProperty&lt;/SPAN&gt;(PropName,DefaultValue=&lt;SPAN class=cb2&gt;MyValues&lt;/SPAN&gt;.V1)]&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;public&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;MyValues&lt;/SPAN&gt; Value&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;get&lt;/SPAN&gt; { &lt;SPAN class=cb1&gt;return&lt;/SPAN&gt; (&lt;SPAN class=cb2&gt;MyValues&lt;/SPAN&gt;) &lt;SPAN class=cb1&gt;this&lt;/SPAN&gt;[PropName]; }&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;class&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;Program&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;static&lt;/SPAN&gt; &lt;SPAN class=cb1&gt;void&lt;/SPAN&gt; Main(&lt;SPAN class=cb1&gt;string&lt;/SPAN&gt;[] args)&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb2&gt;Check&lt;/SPAN&gt; c = &lt;SPAN class=cb1&gt;new&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;Check&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb2 style="COLOR: rgb(255,0,0); BACKGROUND-COLOR: rgb(255,255,255)"&gt;MyValues&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0); BACKGROUND-COLOR: rgb(255,255,255)"&gt; defValue = c.Value;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN class=cb4 style="COLOR: rgb(255,0,0); BACKGROUND-COLOR: rgb(255,255,255)"&gt;// get default value&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P class=cl&gt;}&lt;/P&gt;&lt;/DIV&gt;&lt;BR&gt;The program will work without problem when used as is. But after decompiling with the /CAVERBAL option and recompiling you will get a nasty runtime exception:&lt;BR&gt;&lt;BR&gt;&lt;SMALL&gt;&lt;SMALL&gt;&lt;BIG style="FONT-WEIGHT: bold"&gt;&lt;BIG&gt;Unhandled Exception: System.Configuration.ConfigurationErrorsException: &lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;The default value for the property 'Name' has different type than the one of the property itself.&lt;/BIG&gt;&lt;/BIG&gt;&lt;BR&gt;&lt;/SMALL&gt;&lt;/SMALL&gt;&lt;BR&gt;Here is the innocent looking IL code &lt;BR&gt;&lt;SMALL&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; .custom instance void&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [System.Configuration]System.Configuration.ConfigurationPropertyAttribute::.ctor(string)&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = {&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; string('Name')&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; property object 'DefaultValue' = object( int32(0) )&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;}&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;/SMALL&gt;&lt;BR&gt;The ConfigurationProperty DefaultValue does not preserve type identity for enums but does simply declare them as its native integer value which will lead to this exception during run time because there is an extra check code in the BCL code. The generated IL code&amp;nbsp;is valid for the CLR but not for the BCL. Signer does get around this issue by decompiling every assembly&amp;nbsp;once with the parser friendly /CAVERBAL option and the second time without. It will then merge the binary blobs for the ConfigurationProperty Attributes into the other IL file to get a fully functional assembly. Once this obstacle was solved all worked perfectly. &lt;BR&gt;&lt;BR&gt;
&lt;H2&gt;&lt;SPAN style="FONT-WEIGHT: bold"&gt;Signer Usage&lt;/SPAN&gt;&lt;/H2&gt;If you start Signer without any options you will get a pretty self explanatory help to do signing. The only thing to remeber is that the .NET Framework tool sn &amp;nbsp;is needed to generate a strong name key pair by simply executing sn -k c:\key.snk and you are ready to use Signer out of the box with your project.&lt;BR&gt;&lt;BR&gt;&lt;SMALL&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;Signer (C) by Alois Kraus 2007 (akraus1@gmx.de) version 1.0.0.0&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;Signer -k &amp;lt;KeyFile&amp;gt; -outdir &amp;lt;Output Dir&amp;gt; -a &amp;lt;Assembly1&amp;gt; &amp;lt;Assembly2&amp;gt; ... [-decomp "Options" -comp "Options" -debug]&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp; Signer does sign all assemblies and updates their references if the assembly is not already signed&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp; This way you can convert a whole bunch of assemblies which have never seen a key file into strong named assemblies without recompiling!&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp; -k&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Key File name of key container file which is created usually by the sign tool (sn -k)&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp; -outdir&amp;nbsp;&amp;nbsp; Output directory where the strong signed assemblies are copied to&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp; -decomp&amp;nbsp;&amp;nbsp; Additional ildasm options e.g. "/STATS"&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp; -comp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Additional ilasm options e.g. "/X64"&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp; -a&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Can be a list of assembly names or a wildcard search pattern e.g. *.dll&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp; -debug&amp;nbsp;&amp;nbsp;&amp;nbsp; Do not delete temporary IL files in %TEMP% flder after completion&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;Example: Signer -k c:\key.snk -outdir .\build -a *.dll *.exe&amp;nbsp; Copy the signed assemblies into the newly created directory build.&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;Example: Signer -k c:\key.snk -outdir . -a *.dll *.exe&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Sign and overwrite the orignal binaries in current directory.&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;Error: No Key file specifed (use -k KeyFile ).&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;Error: No Output directory specifed (use -outdir Dir ).&lt;/SPAN&gt;&lt;BR style="FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;Error: No input assemblies specified (use -a Assembly ).&lt;/SPAN&gt;&lt;/SMALL&gt;&lt;BR&gt;&lt;BR&gt;
&lt;H2&gt;&lt;SPAN style="FONT-WEIGHT: bold"&gt;Conclusions&lt;/SPAN&gt;&lt;/H2&gt;It was fun to create the tool while learning quite a lot about the assembly structure, strong names and IL. As you can see strong names are not really a protection for your software as they can be easily removed and your assemblies resigned without big problems. The only real advantage strong names offer is that you can prove that an assembly which has your public key on it was created by you as long as your secret key is kept safe.&lt;BR&gt;From this point other extensions to Signer are quite easy to add. E.g. removal of strong names, make internals public or adding your own InternalsVisibleTo attribute to other assemblies. The world is full of possibilities ;-). &lt;BR&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=104288"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=104288" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/akraus1/aggbug/104288.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Alois Kraus</dc:creator>
            <guid>http://geekswithblogs.net/akraus1/archive/2007/01/23/104288.aspx</guid>
            <pubDate>Wed, 24 Jan 2007 02:21:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/akraus1/comments/104288.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/akraus1/archive/2007/01/23/104288.aspx#feedback</comments>
            <slash:comments>25</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/akraus1/comments/commentRss/104288.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/akraus1/services/trackbacks/104288.aspx</trackback:ping>
        </item>
        <item>
            <title>Cooperative Application Shutdown with the CLR</title>
            <category>General C# Programming</category>
            <link>http://geekswithblogs.net/akraus1/archive/2006/10/30/95435.aspx</link>
            <description>All good things have to end even your perfectly working managed executable. But do you know in what circumstances the CLR will terminate your program and much more importantly when do you have a chance to run some finalizers and shutdown code? As always in live it depends. Lets have a look at the reasons why program execution can be terminated.&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-WEIGHT: bold"&gt;Ways to terminate an application:&lt;/SPAN&gt;&lt;BR&gt;
&lt;OL&gt;
&lt;LI&gt;The last&amp;nbsp; &lt;A href="http://msdn2.microsoft.com/en-us/library/h339syd0.aspx"&gt;foreground&lt;/A&gt; thread of an application ends. The thread which entered the Main function is usually the only&amp;nbsp; foreground thread in your application.&lt;/LI&gt;
&lt;LI&gt;If you run an Windows Forms application you can call &lt;A href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.application.exit.aspx"&gt;System.Windows.Forms.Application.Exit()&lt;/A&gt; to cause Application.Run to return.&lt;/LI&gt;
&lt;LI&gt;When you call &lt;A href="http://msdn2.microsoft.com/en-us/library/system.environment.exit.aspx"&gt;System.Environment.Exit(nn)&lt;/A&gt;.&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;Pressing Ctrl-C or Ctrl-Break inside a Console application.&lt;/LI&gt;
&lt;LI&gt;Call &lt;A href="http://msdn2.microsoft.com/en-us/library/system.environment.failfast.aspx"&gt;System.Environment.FailFast&lt;/A&gt; (new in .NET 2.0) to bail out in case of fatal execution errors.&lt;/LI&gt;
&lt;LI&gt;An unhanded exception in any thread regardless if it is managed or unmanaged.&lt;/LI&gt;
&lt;LI&gt;Unmanaged exit calls within unmanaged code.&lt;/LI&gt;&lt;/OL&gt;What exactly happens during shutdown is explained by an excellent article of &lt;A href="http://blogs.msdn.com/cbrumme/archive/2003/08/20/51504.aspx"&gt;Chris Brumme&lt;/A&gt;.&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-WEIGHT: bold"&gt;Shutdown Process&lt;/SPAN&gt;&lt;BR&gt;Generally speaking we can distinguish between two shutdown types: Cooperative and Abnormal. Cooperative means that you get some help from the CLR (execution guarantees, callback handlers, ...) while the other form of exit is very rude and you will get&amp;nbsp;no help from the runtime. &lt;BR&gt;During a cooperative shutdown the CLR will unload the Application Domain (e.g. after leaving the Main function). This involves killing all threads by doing a hard kill as opposed to the "normal"&amp;nbsp;&lt;A href="http://msdn2.microsoft.com/en-us/library/system.threading.threadabortexception.aspx"&gt;ThreadAbortException&lt;/A&gt; way where the finally blocks of each thread are executed. In reality the threads to be killed are suspended and never resumed. After all threads sleep the&amp;nbsp;pending&amp;nbsp;finalizers are executed inside the Finalizer thread. Now comes a new type of finalizers into the game which was introduced with .NET 2.0. The &lt;A href="http://msdn2.microsoft.com/en-us/library/system.runtime.constrainedexecution.criticalfinalizerobject.aspx"&gt;Critical Finalizers&lt;/A&gt; are guaranteed to be called even when normal finalization did timeout (for .NET 2.0 the time is 40s&amp;nbsp;) and further finalizer processing is aborted.&amp;nbsp;If you trigger an exception inside a finalizer and it is not catched you will stop any further finalization processing, including the new Critical Finalizers. This behavior should be changed in a future version of the CLR. What are these "safe" finalizers good for when an "unsafe" finalizer can prevent them from running? There is already a separate critical finalizer queue inside the CLR which is processed after the normal finalization process did take place. &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-WEIGHT: bold"&gt;Normal Shutdown&lt;/SPAN&gt;&lt;BR&gt;A fully cooperative shutdown is performed in case of 1, 2 and 3. All managed threads are terminated without further notice but all finalizers are executed. No further notice means that no finally blocks are executed while terminating the thread.&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-WEIGHT: bold"