<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Eddie Garmon's Weblog</title><link>http://weblogs.asp.net/egarmon/default.aspx</link><description>some architecture, some c#</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Doh! Synced Actions and Funcs</title><link>http://weblogs.asp.net/egarmon/archive/2008/07/16/doh-synced-actions-and-funcs.aspx</link><pubDate>Wed, 16 Jul 2008 13:30:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6406810</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=6406810</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2008/07/16/doh-synced-actions-and-funcs.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;After a little more use of the Synchronized&amp;lt;T&amp;gt;,&amp;nbsp;I realized that over half the time I was 'returning true' just to satisfy Func&amp;lt;T, bool&amp;gt; when all that was really needed was an Action&amp;lt;T&amp;gt;.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Read, ReadUpgradeableToWrite, and Write are all overloaded now to take either a Action&amp;lt;T&amp;gt; or a Func&amp;lt;T, TReturn&amp;gt;.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A class="" href="http://weblogs.asp.net/blogs/egarmon/Code/Synchronized.zip" mce_href="http://weblogs.asp.net/blogs/egarmon/Code/Synchronized.zip"&gt;You can get the code here&lt;/A&gt;.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6406810" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/Synchronization/default.aspx">Synchronization</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/.NET/default.aspx">.NET</category></item><item><title>More on Syncronized - upgrade reader to writer</title><link>http://weblogs.asp.net/egarmon/archive/2008/07/11/more-on-syncronized-upgrade-reader-to-writer.aspx</link><pubDate>Fri, 11 Jul 2008 18:14:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6389767</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=6389767</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2008/07/11/more-on-syncronized-upgrade-reader-to-writer.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;In using my new sync wrapper to clean up a bunch of older code,&amp;nbsp;I came across the need to be able to upgrade from a reader to a writer for certain operations. One example of this it to clean up expired items in my my implementation of a Cache.&lt;/P&gt;
&lt;P mce_keep="true"&gt;protected Synchronized&amp;lt;Dictionary&amp;lt;string, ICacheItem&amp;gt;&amp;gt; _syncDictionary = &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new Synchronized&amp;lt;Dictionary&amp;lt;string, ICacheItem&amp;gt;&amp;gt;(new Dictionary&amp;lt;string, ICacheItem&amp;gt;());&lt;BR&gt;...&lt;BR&gt;private void PurgeExpired() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _syncDictionary.ReadUpgradeableToWrite((dictionary, reader) =&amp;gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;ICacheItem&amp;gt; expired = new List&amp;lt;ICacheItem&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (ICacheItem cacheItem in dictionary.Values) {&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; if (cacheItem.IsExpired) {&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; expired.Add(cacheItem);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (expired.Count &amp;gt; 0) {&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; reader.UpgradeToWriter();&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; foreach (ICacheItem cacheItem in expired) {&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; ItemRemovedInternal(cacheItem);&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; dictionary.Remove(cacheItem.CacheKey);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;I cleaned up the code a bit, and am making it available &lt;A class="" href="http://weblogs.asp.net/blogs/egarmon/Code/Synchronized.zip" mce_href="http://weblogs.asp.net/blogs/egarmon/Code/Synchronized.zip"&gt;here&lt;/A&gt;. Free to use, no waranty on fitness. &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6389767" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/Lambdas/default.aspx">Lambdas</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/Synchronization/default.aspx">Synchronization</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Sync Enumerator update.</title><link>http://weblogs.asp.net/egarmon/archive/2008/06/30/sync-enumerator-update.aspx</link><pubDate>Mon, 30 Jun 2008 13:40:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6340252</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=6340252</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2008/06/30/sync-enumerator-update.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;After a few more unit tests, I have fixed an issue with the GetSyncEnumerator method.&lt;/P&gt;
&lt;P mce_keep="true"&gt;The origional had 2 issues. &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;was that the lock was being released too soon.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;was that a write in the middle of a long enumeration would cause a race and/or a&amp;nbsp;deadlock.&lt;/DIV&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P mce_keep="true"&gt;The fix&amp;nbsp;was to 'write' lock for enumeration, and not to 'use' the lock, but to let the design of IDisposable on the enumerator itself&amp;nbsp;work as intended.&lt;/P&gt;
&lt;P mce_keep="true"&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Gets a synchronized enumerator.&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;/// &amp;lt;typeparam name="TValue"&amp;gt;The type of the value.&amp;lt;/typeparam&amp;gt;&lt;BR&gt;/// &amp;lt;param name="getEnumeratorFunction"&amp;gt;The get enumerator function.&amp;lt;/param&amp;gt;&lt;BR&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;BR&gt;public IEnumerator&amp;lt;TValue&amp;gt; GetSynchronizedEnumerator&amp;lt;TValue&amp;gt;(Func&amp;lt;T, IEnumerator&amp;lt;TValue&amp;gt;&amp;gt; getEnumeratorFunction)&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Guard.ArgumentNotNull(getEnumeratorFunction, "getEnumeratorFunction");&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //cheat here and write block for enumeration.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //otherwize a write during a long enumeration can cause a race.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SynchronizedWriter synchronizedWriter = null;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SynchronizedEnumerator&amp;lt;TValue&amp;gt; synchronizedEnumerator = null;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; synchronizedWriter = new SynchronizedWriter(_readerWriter);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerator&amp;lt;TValue&amp;gt; enumerator = getEnumeratorFunction(_instance);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; synchronizedEnumerator = new SynchronizedEnumerator&amp;lt;TValue&amp;gt;(synchronizedWriter, enumerator);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return synchronizedEnumerator;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //When the enumerator disposes, the lock is released.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (synchronizedEnumerator != null) {&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; synchronizedEnumerator.Dispose();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else if (synchronizedWriter != null) {&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; synchronizedWriter.Dispose();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A class="" href="http://weblogs.asp.net/blogs/egarmon/Code/Synchronized.zip" mce_href="http://weblogs.asp.net/blogs/egarmon/Code/Synchronized.zip"&gt;The linked code has been updated.&lt;/A&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6340252" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/Lambdas/default.aspx">Lambdas</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/Synchronization/default.aspx">Synchronization</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Synchronization, ReaderWriterLockSlim, and Lambdas</title><link>http://weblogs.asp.net/egarmon/archive/2008/06/27/synchronization-readerwriterlockslim-and-lambdas.aspx</link><pubDate>Fri, 27 Jun 2008 17:43:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6328239</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=6328239</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2008/06/27/synchronization-readerwriterlockslim-and-lambdas.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;Here is a synchronization wrapper that I wrote to wrap any object, and an implementation of a SynchronizedDictionary to show how to use it.&lt;/P&gt;
&lt;P mce_keep="true"&gt;I offer this code as-is without any waranty to fitness, to the public domain, for any purpose you see fit.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A class="" href="http://weblogs.asp.net/blogs/egarmon/Code/Synchronized.zip" mce_href="http://weblogs.asp.net/blogs/egarmon/Code/Synchronized.zip"&gt;Get a text version of this code here.&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;On with the show: &lt;BR&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;[UPDATE: get the code via the link, only ideas are shown below.]&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Synchronized&amp;lt;T&amp;gt;:&lt;BR&gt;wraps an instance of type T.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Contains 3 functions:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;public TValue Read&amp;lt;TValue&amp;gt;(Func&amp;lt;T, TValue&amp;gt; readFunction)&lt;BR&gt;&amp;nbsp;- inside a reader lock, executes the readFunction.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;public bool Write(Func&amp;lt;T, bool&amp;gt; writeFunction)&lt;BR&gt;&amp;nbsp;- inside a writer lock, executes the writeFunction, which should return the success nature of the write.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;public IEnumerator&amp;lt;TValue&amp;gt; GetSynchronizedEnumerator&amp;lt;TValue&amp;gt;(Func&amp;lt;T, IEnumerator&amp;lt;TValue&amp;gt;&amp;gt; getEnumeratorFunction)&lt;BR&gt;- returns an enumerator wrapped in a lock that releases when it is disposed.&lt;/DIV&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P mce_keep="true"&gt;An example of how to use the Synchronized&amp;lt;T&amp;gt;&amp;nbsp;class:&lt;/P&gt;
&lt;P mce_keep="true"&gt;namespace SynapticPop.DataStructures.Dictionaries {&lt;BR&gt;&amp;nbsp; public class SynchronizedDictionary&amp;lt;TKey, TValue&amp;gt; : IDictionary&amp;lt;TKey, TValue&amp;gt;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private readonly Synchronized&amp;lt;IDictionary&amp;lt;TKey, TValue&amp;gt;&amp;gt; _synchronized;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public SynchronizedDictionary(IDictionary&amp;lt;TKey, TValue&amp;gt; dictionary) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_synchronized = new Synchronized&amp;lt;IDictionary&amp;lt;TKey, TValue&amp;gt;&amp;gt;(dictionary);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public int Count&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get { return _synchronized.Read(dictionary =&amp;gt; dictionary.Count); }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void Add(TKey key, TValue value)&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_synchronized.Write(dictionary =&amp;gt;&amp;nbsp;{&amp;nbsp;dictionary.Add(key, value);&amp;nbsp;return true;&amp;nbsp;});&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public IEnumerator&amp;lt;KeyValuePair&amp;lt;TKey, TValue&amp;gt;&amp;gt; GetEnumerator()&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return _synchronized.GetSynchronizedEnumerator(dictionary =&amp;gt; dictionary.GetEnumerator());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6328239" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/Lambdas/default.aspx">Lambdas</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/Synchronization/default.aspx">Synchronization</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/.NET/default.aspx">.NET</category></item><item><title>NUnit extensions updated for 2.2.2</title><link>http://weblogs.asp.net/egarmon/archive/2005/10/19/427885.aspx</link><pubDate>Wed, 19 Oct 2005 12:55:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:427885</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=427885</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2005/10/19/427885.aspx#comments</comments><description>&lt;p&gt;I have updated the ObjectGraphAssert and TimedTest extensions for NUnit 2.2.2.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.synapticpop.com/code/nunit2_2_extensions.zip"&gt;You can get them here&lt;/a&gt;&lt;/p&gt; &lt;p&gt;per the read me...&lt;/p&gt; &lt;p&gt;ObjectGraphAssert - allows you to compare 2 objects via all their properties, and the properties of all children in sub collections.&lt;br /&gt;TimedTest&amp;nbsp;-&amp;nbsp;a time limited test. This helps keep your long running tests from going over a set amount of time.&lt;br /&gt;There only needs to be one change in the current source of NUnit (2.2.2) to support this version of the timed test. In the TemplateTestCase class, change the method signature of doTestCase from private void to protected virtual void.&lt;/p&gt; &lt;p&gt;Happy Testing&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=427885" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/eXtreme+Programming+in+.Net/default.aspx">eXtreme Programming in .Net</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx">VisualStudio.Net</category></item><item><title>Why a Timed Test in NUnit 2.2?</title><link>http://weblogs.asp.net/egarmon/archive/2005/02/14/372114.aspx</link><pubDate>Mon, 14 Feb 2005 05:38:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:372114</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=372114</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2005/02/14/372114.aspx#comments</comments><description>In response to questions about the value add of Timed Tests in NUnit:

There are several uses for timed tests, here are 6, and an update to the TimedTest code... (&lt;a href="http://weblogs.asp.net/egarmon/archive/2005/02/14/372114.aspx"&gt;read more&lt;/a&gt;)
...(&lt;a href="http://weblogs.asp.net/egarmon/archive/2005/02/14/372114.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=372114" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/eXtreme+Programming+in+.Net/default.aspx">eXtreme Programming in .Net</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx">VisualStudio.Net</category></item><item><title>NUnit 2.2 Timed Tests...</title><link>http://weblogs.asp.net/egarmon/archive/2005/02/09/369657.aspx</link><pubDate>Wed, 09 Feb 2005 07:26:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:369657</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=369657</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2005/02/09/369657.aspx#comments</comments><description>Well I finally got around to working on some more NUnit enhancements. I have finished creating an extension for a timed test with resolution in milliseconds. (&lt;a href="http://weblogs.asp.net/egarmon/archive/2005/02/09/369657.aspx"&gt;read more&lt;/a&gt;)...(&lt;a href="http://weblogs.asp.net/egarmon/archive/2005/02/09/369657.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=369657" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/eXtreme+Programming+in+.Net/default.aspx">eXtreme Programming in .Net</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx">VisualStudio.Net</category></item><item><title>Visual Studio .Net C# Item Templates Version 1.1.0</title><link>http://weblogs.asp.net/egarmon/archive/2005/02/08/369293.aspx</link><pubDate>Tue, 08 Feb 2005 19:54:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:369293</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=369293</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2005/02/08/369293.aspx#comments</comments><description>Updates were made for design time support for the 2 typed collection classes, courtesy Brendan Tompkins. I also updated the Registry class, as I found that it was not in sync with the template that I currently use. (&lt;a htrf="http://weblogs.asp.net/egarmon/archive/2005/02/08/369293.aspx"&gt;read more&lt;/a&gt;)...(&lt;a href="http://weblogs.asp.net/egarmon/archive/2005/02/08/369293.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=369293" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx">VisualStudio.Net</category></item><item><title>More Visual Studio Templates (with Installer)</title><link>http://weblogs.asp.net/egarmon/archive/2005/02/08/368926.aspx</link><pubDate>Tue, 08 Feb 2005 08:06:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:368926</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=368926</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2005/02/08/368926.aspx#comments</comments><description>Due to feedback from local sources, I am urged to share my most common Visual Studio Templates.  Packaged in an installer for both VS 2002 and VS 2003 are the following templates:

a class template, an enumeration template, an exception template, a nunit test template, a registry template, a typed collection template, and a typed hashed collection template ... &lt;a href="http://weblogs.asp.net/egarmon/archive/2005/02/08/368926.aspx"&gt;read more&lt;/a&gt;
...(&lt;a href="http://weblogs.asp.net/egarmon/archive/2005/02/08/368926.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=368926" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx">VisualStudio.Net</category></item><item><title>Cleaning the Visual Studio 2005 MRU list.</title><link>http://weblogs.asp.net/egarmon/archive/2005/02/04/366825.aspx</link><pubDate>Fri, 04 Feb 2005 05:09:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:366825</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=366825</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2005/02/04/366825.aspx#comments</comments><description>After playing with Visual Studio 2005 for a while, I have collecter many a deal link in my most recently used items list. Unfortunately, VS2k5 always shows every item in the MRU list on the start page... (&lt;a href="http://weblogs.asp.net/egarmon/archive/2005/02/04/366825.aspx"&gt;read more&lt;/a&gt;) ...(&lt;a href="http://weblogs.asp.net/egarmon/archive/2005/02/04/366825.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=366825" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx">VisualStudio.Net</category></item><item><title>Quickest way to create a repeating string in c#?</title><link>http://weblogs.asp.net/egarmon/archive/2005/01/12/351707.aspx</link><pubDate>Wed, 12 Jan 2005 20:48:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:351707</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=351707</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2005/01/12/351707.aspx#comments</comments><description>&lt;p&gt;int repeatCount = 10;&lt;br /&gt;string value = "hello world.";&lt;br /&gt;string repeated = string.Join(value, new string[repeatCount + 1]);&lt;br /&gt;Console.WriteLine(repeated);&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=351707" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx">VisualStudio.Net</category></item><item><title>More Extending Nunit (version 2.2)</title><link>http://weblogs.asp.net/egarmon/archive/2005/01/12/351202.aspx</link><pubDate>Wed, 12 Jan 2005 06:08:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:351202</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=351202</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2005/01/12/351202.aspx#comments</comments><description>&lt;p&gt;There is some slight&amp;nbsp;code duplication (from the NUnit framework), but it works with 1.X and 2.0 frameworks...&lt;/p&gt; &lt;p&gt;ObjectGraphAssert and ObjectGraphFixture: &lt;a href="http://www.synapticpop.com/code/objectgraphassert.zip"&gt;Here is the zip.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you create a failing test, please pass it on so&amp;nbsp;I can update my code.&lt;/p&gt; &lt;p&gt;Enjoy&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=351202" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/eXtreme+Programming+in+.Net/default.aspx">eXtreme Programming in .Net</category><category domain="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx">VisualStudio.Net</category></item><item><title>Delimited String Builder</title><link>http://weblogs.asp.net/egarmon/archive/2004/10/29/249869.aspx</link><pubDate>Sat, 30 Oct 2004 01:52:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:249869</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=249869</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2004/10/29/249869.aspx#comments</comments><description>&lt;p&gt;This went out in the DNR chat room... enjoy.&lt;/p&gt; &lt;p&gt;&lt;a href="http://synapticpop.com/code/delimitedstringbuilder.cs.txt"&gt;http://synapticpop.com/code/delimitedstringbuilder.cs.txt&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=249869" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/General/default.aspx">General</category></item><item><title>NewsGator wishlist...</title><link>http://weblogs.asp.net/egarmon/archive/2004/01/23/62193.aspx</link><pubDate>Fri, 23 Jan 2004 16:57:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:62193</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=62193</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2004/01/23/62193.aspx#comments</comments><description>&lt;DIV class=Section1&gt;
&lt;P class=MsoNormal&gt;Number of recent posts to display: Disable or set to 0 causes a bug, Fix.&lt;/P&gt;
&lt;P class=MsoNormal&gt;Mark all read and delete all on folder bars in newspaper view. (specific to folder/subfolders/)&lt;/P&gt;
&lt;P class=MsoNormal&gt;Enable newspaper view on subfolders when they exist. (ie sections of a newspaper.)&lt;/P&gt;
&lt;P class=MsoNormal&gt;Newspaper view: Delete a post, expand any folder below that one, and delete a post in the folder, causes a script error, Fix.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=62193" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/General/default.aspx">General</category></item><item><title>Auto-Incrementing Build Numbers (C# for VS.Net)</title><link>http://weblogs.asp.net/egarmon/archive/2003/12/03/41101.aspx</link><pubDate>Thu, 04 Dec 2003 00:34:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:41101</guid><dc:creator>UltimateRinger</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/egarmon/rsscomments.aspx?PostID=41101</wfw:commentRss><comments>http://weblogs.asp.net/egarmon/archive/2003/12/03/41101.aspx#comments</comments><description>&lt;P&gt;I finally got fed up with manually updating the build numbers in the AssemblyInfo.cs files. I needed an automated solution, so now I have one, even though&amp;nbsp;it is definately more of a hack than good code.&lt;/P&gt;
&lt;P&gt;To the point, I created a simple console app that I placed in my bin directory, and use a Pre-BuildEvent to call. (i.e. BuildNumberIncrementer &amp;#8220;Path to a\AssemblyInfo.cs&amp;#8221;).&lt;/P&gt;
&lt;P&gt;The hack that is &lt;A href="http://www.synapticpop.com/code/BuildNumberIncrementer.cs.txt"&gt;BuildNumberIncrementer&lt;/A&gt; goes like :&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;STYLE type=text/css&gt;
.csharpcode
{
 font-size: 10pt;
 color: black;
 font-family: Courier New , Courier, Monospace;
 background-color: #ffffff;
 /*white-space: pre;*/
}
.csharpcode pre { margin: 0px; }
.rem { color: #008000; }
.kwrd { color: #0000ff; }
.str { color: #006080; }
.op { color: #0000c0; }
.preproc { color: #cc6633; }
.asp { background-color: #ffff00; }
.html { color: #800000; }
.attr { color: #ff0000; }
.alt 
{
 background-color: #f4f4f4;
 width: 100%;
 margin: 0px;
}
.lnum { color: #606060; }
&lt;/STYLE&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.IO;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Text.RegularExpressions;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;namespace&lt;/SPAN&gt; BuildNumberIncrementer {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; EntryPoint {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;        [STAThread]&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Main(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;[] args) {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (args.Length != 1) {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;                Console.WriteLine(&lt;SPAN class=str&gt;"Please specify the 'AssemblyInfo.cs' you want to update."&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;                &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;            }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; infoPath = args[0];&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  15:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (!infoPath.EndsWith(&lt;SPAN class=str&gt;"AssemblyInfo.cs"&lt;/SPAN&gt;)) {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  16:  &lt;/SPAN&gt;                Console.WriteLine(&lt;SPAN class=str&gt;"Please specify the 'AssemblyInfo.cs' you want to update."&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  17:  &lt;/SPAN&gt;                &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  18:  &lt;/SPAN&gt;            }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  19:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  20:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (!File.Exists(infoPath)) {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  21:  &lt;/SPAN&gt;                Console.WriteLine(infoPath + &lt;SPAN class=str&gt;" does not exist."&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  22:  &lt;/SPAN&gt;                &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  23:  &lt;/SPAN&gt;            }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  24:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  25:  &lt;/SPAN&gt;            StreamReader reader = File.OpenText(infoPath);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  26:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; contents = reader.ReadToEnd();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  27:  &lt;/SPAN&gt;            reader.Close();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  28:  &lt;/SPAN&gt;            Regex version = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Regex(&lt;SPAN class=str&gt;@"(\d+\.\d+\.\d+\.)(\d+)"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  29:  &lt;/SPAN&gt;            Match versionMatch = version.Match(contents);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  30:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; oldVersion = versionMatch.Value;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  31:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; newVersion = versionMatch.Groups[1].Value + (Convert.ToUInt32(versionMatch.Groups[2].Value) + 1).ToString();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  32:  &lt;/SPAN&gt;            contents = contents.Replace(oldVersion, newVersion);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  33:  &lt;/SPAN&gt;            StreamWriter writer = File.CreateText(infoPath);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  34:  &lt;/SPAN&gt;            writer.Write(contents);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  35:  &lt;/SPAN&gt;            writer.Close();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  36:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  37:  &lt;/SPAN&gt;            Console.WriteLine(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;.Format(&lt;SPAN class=str&gt;"New version is [{0}]"&lt;/SPAN&gt;, newVersion));&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  38:  &lt;/SPAN&gt;        }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  39:  &lt;/SPAN&gt;    }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  40:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=41101" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx">VisualStudio.Net</category></item></channel></rss>