<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Eddie Garmon's Weblog</title><subtitle type="html">some architecture, some c#</subtitle><id>http://weblogs.asp.net/egarmon/atom.aspx</id><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/default.aspx" /><link rel="self" type="application/atom+xml" href="http://weblogs.asp.net/egarmon/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20510.895">Community Server</generator><updated>2003-12-03T19:34:00Z</updated><entry><title>Doh! Synced Actions and Funcs</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2008/07/16/doh-synced-actions-and-funcs.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2008/07/16/doh-synced-actions-and-funcs.aspx</id><published>2008-07-16T13:30:00Z</published><updated>2008-07-16T13:30:00Z</updated><content type="html">&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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="Synchronization" scheme="http://weblogs.asp.net/egarmon/archive/tags/Synchronization/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/egarmon/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/egarmon/archive/tags/.NET/default.aspx" /></entry><entry><title>More on Syncronized - upgrade reader to writer</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2008/07/11/more-on-syncronized-upgrade-reader-to-writer.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2008/07/11/more-on-syncronized-upgrade-reader-to-writer.aspx</id><published>2008-07-11T18:14:00Z</published><updated>2008-07-11T18:14:00Z</updated><content type="html">&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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="Lambdas" scheme="http://weblogs.asp.net/egarmon/archive/tags/Lambdas/default.aspx" /><category term="Synchronization" scheme="http://weblogs.asp.net/egarmon/archive/tags/Synchronization/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/egarmon/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/egarmon/archive/tags/.NET/default.aspx" /></entry><entry><title>Sync Enumerator update.</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2008/06/30/sync-enumerator-update.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2008/06/30/sync-enumerator-update.aspx</id><published>2008-06-30T13:40:00Z</published><updated>2008-06-30T13:40:00Z</updated><content type="html">&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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="Lambdas" scheme="http://weblogs.asp.net/egarmon/archive/tags/Lambdas/default.aspx" /><category term="Synchronization" scheme="http://weblogs.asp.net/egarmon/archive/tags/Synchronization/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/egarmon/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/egarmon/archive/tags/.NET/default.aspx" /></entry><entry><title>Synchronization, ReaderWriterLockSlim, and Lambdas</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2008/06/27/synchronization-readerwriterlockslim-and-lambdas.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2008/06/27/synchronization-readerwriterlockslim-and-lambdas.aspx</id><published>2008-06-27T17:43:00Z</published><updated>2008-06-27T17:43:00Z</updated><content type="html">&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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="Lambdas" scheme="http://weblogs.asp.net/egarmon/archive/tags/Lambdas/default.aspx" /><category term="Synchronization" scheme="http://weblogs.asp.net/egarmon/archive/tags/Synchronization/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/egarmon/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/egarmon/archive/tags/.NET/default.aspx" /></entry><entry><title>NUnit extensions updated for 2.2.2</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2005/10/19/427885.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2005/10/19/427885.aspx</id><published>2005-10-19T12:55:00Z</published><updated>2005-10-19T12:55:00Z</updated><content type="html">&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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="eXtreme Programming in .Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/eXtreme+Programming+in+.Net/default.aspx" /><category term="VisualStudio.Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx" /></entry><entry><title>Why a Timed Test in NUnit 2.2?</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2005/02/14/372114.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2005/02/14/372114.aspx</id><published>2005-02-14T05:38:00Z</published><updated>2005-02-14T05:38:00Z</updated><content type="html">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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="eXtreme Programming in .Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/eXtreme+Programming+in+.Net/default.aspx" /><category term="VisualStudio.Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx" /></entry><entry><title>NUnit 2.2 Timed Tests...</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2005/02/09/369657.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2005/02/09/369657.aspx</id><published>2005-02-09T07:26:00Z</published><updated>2005-02-09T07:26:00Z</updated><content type="html">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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="eXtreme Programming in .Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/eXtreme+Programming+in+.Net/default.aspx" /><category term="VisualStudio.Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx" /></entry><entry><title>Visual Studio .Net C# Item Templates Version 1.1.0</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2005/02/08/369293.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2005/02/08/369293.aspx</id><published>2005-02-08T19:54:00Z</published><updated>2005-02-08T19:54:00Z</updated><content type="html">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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="VisualStudio.Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx" /></entry><entry><title>More Visual Studio Templates (with Installer)</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2005/02/08/368926.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2005/02/08/368926.aspx</id><published>2005-02-08T08:06:00Z</published><updated>2005-02-08T08:06:00Z</updated><content type="html">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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="VisualStudio.Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx" /></entry><entry><title>Cleaning the Visual Studio 2005 MRU list.</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2005/02/04/366825.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2005/02/04/366825.aspx</id><published>2005-02-04T05:09:00Z</published><updated>2005-02-04T05:09:00Z</updated><content type="html">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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="VisualStudio.Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx" /></entry><entry><title>Quickest way to create a repeating string in c#?</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2005/01/12/351707.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2005/01/12/351707.aspx</id><published>2005-01-12T20:48:00Z</published><updated>2005-01-12T20:48:00Z</updated><content type="html">&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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="VisualStudio.Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx" /></entry><entry><title>More Extending Nunit (version 2.2)</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2005/01/12/351202.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2005/01/12/351202.aspx</id><published>2005-01-12T06:08:00Z</published><updated>2005-01-12T06:08:00Z</updated><content type="html">&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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="eXtreme Programming in .Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/eXtreme+Programming+in+.Net/default.aspx" /><category term="VisualStudio.Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx" /></entry><entry><title>Delimited String Builder</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2004/10/29/249869.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2004/10/29/249869.aspx</id><published>2004-10-30T01:52:00Z</published><updated>2004-10-30T01:52:00Z</updated><content type="html">&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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="General" scheme="http://weblogs.asp.net/egarmon/archive/tags/General/default.aspx" /></entry><entry><title>NewsGator wishlist...</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2004/01/23/62193.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2004/01/23/62193.aspx</id><published>2004-01-23T16:57:00Z</published><updated>2004-01-23T16:57:00Z</updated><content type="html">&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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="General" scheme="http://weblogs.asp.net/egarmon/archive/tags/General/default.aspx" /></entry><entry><title>Auto-Incrementing Build Numbers (C# for VS.Net)</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/egarmon/archive/2003/12/03/41101.aspx" /><id>http://weblogs.asp.net/egarmon/archive/2003/12/03/41101.aspx</id><published>2003-12-04T00:34:00Z</published><updated>2003-12-04T00:34:00Z</updated><content type="html">&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;</content><author><name>UltimateRinger</name><uri>http://weblogs.asp.net/members/UltimateRinger.aspx</uri></author><category term="VisualStudio.Net" scheme="http://weblogs.asp.net/egarmon/archive/tags/VisualStudio.Net/default.aspx" /></entry></feed>