<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devplanet.com/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/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"><channel><title>devplanet.com</title><link>http://devplanet.com/blogs/</link><description>a community devoted to .NET and MS SQL developers</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 (Build: 30912.2823)</generator><item><title>Thread Safe Library Update</title><link>http://devplanet.com/blogs/brianr/archive/2009/09/02/thread-safe-library-update.aspx</link><pubDate>Wed, 02 Sep 2009 16:33:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:15986</guid><dc:creator>Brian Rudolph</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;As always, my life revolves around threading.&amp;nbsp; So&amp;nbsp;I have a few classes that I use frequently for these purposes.&amp;nbsp; Now, fortunately, .NET 4.0 will include much of this functionality in PFX, but for now, we have this.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devplanet.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/brianr/ThreadSafe.zip"&gt;ThreadSafeLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AutoProcessingQueue&lt;/strong&gt;: This is a queue that as you add things to it, will automatically begin dispatching on a seperate thread and begin calling a specified delegate to process the items.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Batch&lt;/strong&gt;: This is a class that is similar to a queue except that it allows you to do work in batches.&amp;nbsp; Set the max &amp;amp; minimum sizes, and start adding items to it.&amp;nbsp; When it reaches a certain size it will attempt to close the batch and will fire an event that will allow you to wire in code for processing the data in the batch.&amp;nbsp; It also has a timer that can be enabled if you&amp;#39;d prefer to allow the batch to be closed at a certain interval.&amp;nbsp; This is great for database calls and bulk inserts.&amp;nbsp; Say I want to send a series of messages, but i don&amp;#39;t want to send them one at a time.&amp;nbsp; I would like to send the messages when the batch reaches 100 items, or every 5 seconds.&amp;nbsp; I use this class alot for messaging.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dispatcher&lt;/strong&gt;:&amp;nbsp; This is the class that does the heavy lifting for the majority of things in this library.&amp;nbsp; You give it a maximum number of threads to work with, and as you add workers to it&amp;#39;s queue, it will begin spawning threads to process them(carefully re-using them whenever possible)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ResourcePool&lt;/strong&gt;:&amp;nbsp; The dispatcher uses this internally to store &amp;amp; manage it&amp;#39;s threads.&amp;nbsp; Though it can be used for any object type.&amp;nbsp; One case where i use this frequently is to pool connections to webservices.&amp;nbsp; To save the time required to open and close connections constantly, i set up a pool, give it a threshold(so as to not flood the service i&amp;#39;m calling) and ask it to get the resource for you via the delegate you provide.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ThreadSafeDictionary&amp;lt;K,V&amp;gt;&lt;/strong&gt;:&amp;nbsp; The classic threadsafe implementation of a dictionary, with several added methods to support atomic operations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ThreadSafeQueue&amp;lt;T&amp;gt;&lt;/strong&gt;:&amp;nbsp; The classic Queue implementation of a dictionary, with several added methods to support atomic operations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ThreadSafeHashSet&amp;lt;T&amp;gt;&lt;/strong&gt;:&amp;nbsp; The classic HashSet implementation of a dictionary, with several added methods to support atomic operations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ThreadSafeStackList&amp;lt;T&amp;gt;&lt;/strong&gt;:&amp;nbsp; This is similar to a stack, without alot of the limitations.&amp;nbsp; Multi-level peek, unwind, etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AsyncBlock&lt;/strong&gt;:&lt;br /&gt;This is a class that allows you to wrap async work into serial action for the purposes of simplicity.&amp;nbsp; If you need have a function that needs to run numerous asynchronous calls, and then return only when they are all finished, this is your class.&lt;/p&gt;
&lt;p&gt;You can use it like so:&lt;/p&gt;
&lt;p&gt;&lt;table cellpadding="0" cellspacing="0" style="background-color:#f2f2f2;border:solid 1px #e5e5e5;width:100%;"&gt;
&lt;tr style="vertical-align:top;line-height:normal;"&gt;&lt;td&gt;&lt;pre style="overflow:scroll;margin:0px;padding:2px;padding-left:8px;"&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;     &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; AsyncSample
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; Dispatcher Dispatcher;


        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; AsyncSample()
        {
            &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//init a dispatcher that uses 5 threads and doesn&amp;#39;t carry execution context&lt;/span&gt;
            Dispatcher &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; Dispatcher(5, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;);
        }


        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; ExecuteParallel&amp;lt;T&amp;gt;(IList&amp;lt;T&amp;gt; work)
        {
            var workers &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; ConstructParallelWorkers(work);


            &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//the async block will pause this thread until all workers finish&lt;/span&gt;
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (AsyncBlock block &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; AsyncBlock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Dispatcher, 10))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;foreach&lt;/span&gt; (var worker &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;in&lt;/span&gt; workers)
                {
                    block.AddToQueue(worker);
                }
            }
        }


        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; IList&amp;lt;AnyWorkerBee&amp;lt;T&amp;gt;&amp;gt; ConstructParallelWorkers&amp;lt;T&amp;gt;(IList&amp;lt;T&amp;gt; work)
        {
            var workers &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; List&amp;lt;AnyWorkerBee&amp;lt;T&amp;gt;&amp;gt;();


            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;foreach&lt;/span&gt; (var workUnit &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;in&lt;/span&gt; work)
                workers.Add(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; AnyWorkerBee&amp;lt;T&amp;gt;() { WorkUnit &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; workUnit });


            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; workers;
        }
    }&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=15986" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/brianr/archive/tags/Threading/default.aspx">Threading</category><category domain="http://devplanet.com/blogs/brianr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://devplanet.com/blogs/brianr/archive/tags/Async/default.aspx">Async</category><category domain="http://devplanet.com/blogs/brianr/archive/tags/IDisposable/default.aspx">IDisposable</category></item><item><title>Thirsty Developer Interview Posted</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2009/04/28/thirsty-developer-interview-posted.aspx</link><pubDate>Tue, 28 Apr 2009 22:26:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:15911</guid><dc:creator>Chuck</dc:creator><slash:comments>0</slash:comments><description>&lt;p class="MsoNormal" style="margin:0in 0in 10pt;"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;For those of you interested, I have recorded an interview with The Thirsty Developer (&lt;a href="http://www.thirstydeveloper.com"&gt;http://www.thirstydeveloper.com&lt;/a&gt;).&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;The interview is based around a user group presentation that I give about the new features of SQL Server 2008 for developers.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin:0in 0in 10pt;"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;I do need to clarify one statement in the interview.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;We were talking about spatial data and support for the Z dimension.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;We talk about SQL Server&amp;#39;s support for Z, and I want to clarify that SQL Server will allow you to store the Z dimension with points but it will not use Z in calculations.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin:0in 0in 10pt;"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;Thank you to Larry Clarkin and Dave Bost for inviting me to participate in their project.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin:0in 0in 10pt;"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;Chuck&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=15911" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/SQL+Server+2008/default.aspx">SQL Server 2008</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Column+Sets/default.aspx">Column Sets</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Spatial/default.aspx">Spatial</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/New+Features/default.aspx">New Features</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Filestream/default.aspx">Filestream</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Thirsty+Developer/default.aspx">Thirsty Developer</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Sparse+Columns/default.aspx">Sparse Columns</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Developer/default.aspx">Developer</category></item><item><title>SQL Server 2008 Backup Compression</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2009/04/20/sql-server-2008-backup-compression.aspx</link><pubDate>Tue, 21 Apr 2009 03:00:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:15854</guid><dc:creator>Chuck</dc:creator><slash:comments>0</slash:comments><description>&lt;p class="MsoNormal" style="margin:0in 0in 10pt;"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;With SQL Server 2008, Microsoft introduced native backup compression.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Prior to SQL Server 2008, the only way to get real-time backup compression was to buy a third-party tool.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;There were &amp;ndash; and still are &amp;ndash; several third-party tools on the market.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;I have used a few of them, and they each have their pros and cons.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;But, this post is not to debate the merits of the different tools &amp;ndash; it is to discuss the native functionality that ships with SQL Server 2008.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin:0in 0in 10pt;"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;If you&amp;rsquo;ve ever used an off-the-shelf compression utility (such as WinZip) on a SQL Server native backup, you&amp;rsquo;ve probably noticed that they usually compress down quite well.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;I&amp;rsquo;ve seen certain backups compress down 75% or more.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;The problem with this method is that you need a lot of disk to make it happen.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;If you have a 10GB database, a full backup will take 10GB of disk space.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;If that backup achieves 75% compression, if will end up taking up 2.5GB of disk space.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;The problem is that you really need 12.5GB of disk to get to a 2.5GB compressed backup (10GB for the initial backup then an additional 2.5GB for the compression).&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Now, increase the size of your database by 10 or 100 times.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Do you really have an extra 1TB of disk lying around so that you can end up with a 250GB backup?&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;I certainly don&amp;rsquo;t.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin:0in 0in 10pt;"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;This is where SQL Server&amp;rsquo;s native backup compression can really help.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;The compression happens as the data is being written to disk, not after it is there.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;So, if you have a 10GB database that will achieve 75% compression, you only need 2.5GB of disk to perform the backup &amp;ndash; not 10GB like you would without compression.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin:0in 0in 10pt;"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;From my experience, the native backup compression performs quite well, although your mileage may vary.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;You will have additional processor overhead above and beyond the overhead required for a standard backup, but in my testing the overhead was comparable to what I was getting with several of the third-party tools.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin:0in 0in 10pt;"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;I don&amp;rsquo;t want it to sound like I&amp;rsquo;m against the third-party tools.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;I still use a third-party backup utility where it makes sense.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Remember that the native backup compression won&amp;rsquo;t fit all situations &amp;ndash; most of the third-party tools include encryption and other features that are not included in the native solution &amp;ndash; and there isn&amp;rsquo;t a nice management console like what you get with the third party tools.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;But, if you can live without these added features, you might be able to save some money by using the native backups.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin:0in 0in 10pt;"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;The best advice that I can give you is to give it a try and gather metrics to compare your third-party tool to the native compressed backups.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Look at the backup time, restore time, processor utilization and final compressed size.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;If your experiences are similar to mine, I am guessing that you will be quite impressed.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;Chuck&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=15854" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/SQL+Server+2008/default.aspx">SQL Server 2008</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Backup/default.aspx">Backup</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Native/default.aspx">Native</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Compression/default.aspx">Compression</category></item><item><title>PASS Call for Presentations - You've Got Through April 24, 2009</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2009/04/19/pass-call-for-presentations-you-ve-got-through-april-24-2009.aspx</link><pubDate>Mon, 20 Apr 2009 00:59:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:15832</guid><dc:creator>Chuck</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Those of you who know me know that I am a big supporter of the Professional Association for SQL Server (PASS).&amp;nbsp; I have been involved with this organization since 2000 - when I spoke at their North American conference in San Francisco.&amp;nbsp; Since then I have held a variety of volunteer positions including author, editor, presenter and - for a few years - member of the Board of Directors.&lt;/p&gt;
&lt;p&gt;I can&amp;#39;t express enough how important I believe this organization is to the SQL Server community.&amp;nbsp; The annual conference is a hotbed of SQL Server education.&amp;nbsp; In my opinion, you won&amp;#39;t find any better source for high-end, high-quality SQL Server speakers and presentations.&amp;nbsp; In reality, PASS is much more than the annual conference - but I&amp;#39;m here to talk about the conference.&lt;/p&gt;
&lt;p&gt;Each year PASS requests presentation abstracts from members of the SQL Server community.&amp;nbsp; It has been like that all along (that&amp;#39;s how I got my start with PASS).&amp;nbsp; The non-Microsoft speaking slots at the conference are filled by a committee of volunteers who review and evaluate the submissions that are received.&amp;nbsp; This is a daunting task, and I truly appreciate the people who do it.&lt;/p&gt;
&lt;p&gt;I would like to encourage anyone who has ever thought - or even if you have never thought -&amp;nbsp;about presenting at a conference to hit &lt;a href="http://www.sqlpass.org"&gt;www.sqlpass.org&lt;/a&gt; and submit an abstract.&amp;nbsp; If you&amp;#39;ve got something that others might be interested in hearing about, write it up.&amp;nbsp; Speaking at an event like this is not as hard as you might think - it&amp;#39;s actually quite fun.&lt;/p&gt;
&lt;p&gt;You can submit up to four abstracts.&amp;nbsp; Now go forth and submit!&lt;/p&gt;
&lt;p&gt;Chuck&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=15832" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Presentations/default.aspx">Presentations</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/PASS/default.aspx">PASS</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/PASS+Community+Summit/default.aspx">PASS Community Summit</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Conferences/default.aspx">Conferences</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Abstracts/default.aspx">Abstracts</category></item><item><title>HashSet Deserialization Oddities</title><link>http://devplanet.com/blogs/brianr/archive/2009/03/25/hashset-deserialization-oddities.aspx</link><pubDate>Wed, 25 Mar 2009 14:15:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:15515</guid><dc:creator>Brian Rudolph</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;So, yesterday was a fun day.&amp;nbsp; I spent all day trying to debug a state in which one of your QA web servers&amp;#39; worker processes would go into an infinite loop and peg a core on the CPU.&amp;nbsp; After many hours, and finally installing the remote debugging tools on the server, I eventually found the problem - removing an item from a HashSet. ?!?&lt;/p&gt;
&lt;p&gt;So let me set the scenario up.&amp;nbsp; I have a website that runs in a farm, so I utilize SQL for state management.&amp;nbsp; As you probably already know, all objects that go into state are binary serialized, forwarded to the SQL server, and then fetched and deserialized upon request after the next page load.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I have a state object that is placed in to session state.&amp;nbsp; It contains&amp;nbsp;some state that is a&amp;nbsp;HashSet&amp;lt;Guid&amp;gt; object.&amp;nbsp; The first time this object is put into state, it is empty.&amp;nbsp; I then retrieve it and place a few guids into it.&amp;nbsp; This is where it gets odd.&amp;nbsp; If i browse the object after I add the guids to it, it appears that some of them go in to the set as Empty Guids, regardless of their value when i actually added them.&amp;nbsp; This is after the set has been deserialized from state empty, then values added to it.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Interestingly enough, it actually adds multiple duplicate keys to the set, which is natively not permissable.&amp;nbsp; Under normal circumstances, were I to add Guid.Empty into a hashset 3 times, it will only appear in the set once.&amp;nbsp; Not in this case.&amp;nbsp; It appears that the set is checking for uniqueness with the real value being passed in, detects that the value is unique, yet after the value is added it is actually added as Guid.Empty.&amp;nbsp; So this would be crazy enough... but thats not where the story ends.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Now, a few methods away I am tearing through the values in the set, and removing ones that meet a certain condition.&amp;nbsp; Except that since I am receiving empty guids back for most of the items i put in the set, these are always meeting my removal condition.&amp;nbsp; Aside from the craziness, this shouldn&amp;#39;t be a huge problem, except that when i go to remove one of the empty guids from the set, within framework code it gets stuck in an infinite loop.&amp;nbsp; I have not Reflected this to see where, but i would guess that it is not pleased having duplicate keys internally.&amp;nbsp; Interestingly enough, if i replace the hashset with a List&amp;lt;Guid&amp;gt;, all is well.&lt;/p&gt;
&lt;p&gt;So here&amp;#39;s the kicker.&amp;nbsp; This is not reproducible on my development box, only on this QA server.&amp;nbsp; The possible reasons are many.&amp;nbsp; For instance, my dev box runs .Net 3.5 SP1, while the server is running without SP1.&amp;nbsp; My dev box is running Vista x64 hosting under cassini, while the server is running Server 2008 x64 hosting under IIS 7.&amp;nbsp; My guess for the culprit would be the former.&amp;nbsp; I am upgrading the server to SP1 today to see if that resolves the issue.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I will update this post with the results.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=15515" width="1" height="1"&gt;</description></item><item><title>MSCS Clusters, iSCSI, Distance Clusters and SQL 2005</title><link>http://devplanet.com/blogs/steineke/archive/2009/03/06/mscs-clusters-iscsi-distance-clusters-and-sql-2005.aspx</link><pubDate>Sat, 07 Mar 2009 05:30:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:15085</guid><dc:creator>Michael Steineke</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;
&lt;p&gt;This has been a fun week with clustering.&amp;nbsp; Myself and a few others have been working this week on setting up a couple lab environments.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Lab 1: &lt;/b&gt;&lt;br /&gt;2 - Hyper-V Windows 2003 R2 Enterprise 64Bit VM&amp;#39;s&lt;br /&gt;iSCSI LUNS&lt;br /&gt;MSCS Shared Quorum Cluster&lt;br /&gt;1 - SQL Server 2005 sp2 3159 clustered instance&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Lab 2:&lt;/b&gt;&lt;br /&gt;2 - Dual Quad Core Xeon servers running Windows 2003 R2 Enterprise 64Bit&lt;br /&gt;SAN attached LUNS&lt;br /&gt;MSCS Shared Quorum Cluster&lt;br /&gt;1 - SQL Server 2005 sp2 3159 clustered instance&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The kicker with LAB 2 is that the two servers are ~850 miles apart using two different SAN&amp;#39;s, but more on that later.&amp;nbsp; Lab 1s configuration went smoothly, having not done iSCSI in a cluster before this install it was a learning experience, but overall very similar to using FC attached disk. &amp;nbsp;The process that Brian has posted for configuring MSDTC in a &lt;a href="http://devplanet.com/blogs/brianr/archive/2008/01/14/ms-dtc-configuration-for-sql-2005-in-a-distance-cluster-on-windows-server-2003-datacenter.aspx"&gt;Cluster&lt;/a&gt; was helpful, and worked perfectly.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Lab 2 was slightly more complicated, but only because of having a few more steps; it is using &lt;a href="http://ecommunity.unisys.com/unisys/solution_center/sc_documents/whitepaper/41267519-000.pdf"&gt;Unisys SafeGuard 30m Clustering&lt;/a&gt;.&amp;nbsp; The Unisys documentation was spot-on; it covered every step necessary to configure everything in 30m, as well as MSCS. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://devplanet.com/cfs-file.ashx/__key/CommunityServer.Components.UserFiles/00.00.00.21.22/Basic-30M.gif"&gt;&lt;img align="middle" width="300" src="http://devplanet.com/cfs-file.ashx/__key/CommunityServer.Components.UserFiles/00.00.00.21.22/Basic-30M.gif" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;span style="font-size:small;font-family:Calibri;"&gt;
&lt;p&gt;
&lt;p&gt;Above is the basic configuration for the distance cluster.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The SQL servers have a splitter driver loaded on them that splits all writes to the cluster disk resources to both the SAN and the 30m appliances via the SAN Fabric.&amp;nbsp; The 30m appliances then handle all of the block level replication to the distance SAN, as well as provide control resources to MSCS to make sure all of the disk is consistent prior to brining the resources on-line.&amp;nbsp; The whole system is very cool, and in my opinion under-marketed.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=15085" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/steineke/archive/tags/Distance+Cluster/default.aspx">Distance Cluster</category><category domain="http://devplanet.com/blogs/steineke/archive/tags/MSCS+Cluster/default.aspx">MSCS Cluster</category><category domain="http://devplanet.com/blogs/steineke/archive/tags/30m/default.aspx">30m</category></item><item><title>SQL Server 2008 Upgrade Woes</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2009/03/02/sql-server-2008-upgrade-woes.aspx</link><pubDate>Mon, 02 Mar 2009 22:37:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:14942</guid><dc:creator>Chuck</dc:creator><slash:comments>0</slash:comments><description>&lt;p style="margin:0in 0in 0pt;" class="MsoNoSpacing"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Tahoma&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;I&amp;rsquo;ve been working on upgrading an application from SQL Server 2005 to SQL Server 2008.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Simple process, right?&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Well, I ran into a few issues along the way that I thought I would share with you.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0pt;" class="MsoNoSpacing"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Tahoma&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0pt;" class="MsoNoSpacing"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Tahoma&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;First, make sure that your processor configuration matches your affinity mask.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;You might be thinking that I&amp;rsquo;m crazy right now, but it is a problem that I think more people will run into.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Take the following example:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0pt 0.5in;" class="MsoNoSpacing"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Tahoma&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;You are planning to upgrade a production system and you want to test it before you do the upgrade.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Your production server has 8 processor cores and you have an affinity mask set to use cores 0, 2, 4 and 6.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;You take a P to V image of your production system and stand it up in a virtual environment (such as HyperV), but that virtual environment only has 4 processor cores configured.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0pt;" class="MsoNoSpacing"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Tahoma&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;In this scenario, the upgrade will fail.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;The user interface will not tell you exactly what went wrong&amp;hellip;rather it will direct you to a log file that is extremely full of information.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;When you finally find the error message in the log file, you will find that it could not do the upgrade because the affinity mask could not be set.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0pt;" class="MsoNoSpacing"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Tahoma&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0pt;" class="MsoNoSpacing"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Tahoma&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;I noticed this when one of my development servers (an 8 core Itanium) was rebooted and only had four cores available when it came back up.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Once I got the other four cores online, the upgrade was able to complete.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0pt;" class="MsoNoSpacing"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Tahoma&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0pt;" class="MsoNoSpacing"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Tahoma&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;The other issue came out of restoring databases.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;I currently use ToolX (name withheld because I don&amp;rsquo;t know if it is the cause) for my production backup software.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;When I upgraded to SQL Server 2008, I used ToolX to restore backups from one of my SQL Server 2005 environments into SQL Server 2008.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;The backups appeared to complete successfully, but when I ran a DBCC CHECKDB on them, some of them had consistency errors that did not exist in the original that the backups were pulled from.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;I had to do a repair_allow_data_loss to get the databases usable again.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0pt;" class="MsoNoSpacing"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Tahoma&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0pt;" class="MsoNoSpacing"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Tahoma&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;I haven&amp;rsquo;t nailed down what the exact cause of the second problem is, but I will post a follow-up when I know.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=14942" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/SQL+Server+2008/default.aspx">SQL Server 2008</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Upgrade/default.aspx">Upgrade</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Affinity+Mask/default.aspx">Affinity Mask</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/DBCC+CHECKDB/default.aspx">DBCC CHECKDB</category></item><item><title>Inline Asynchronous UI Coding using IDisposable in C# .NET</title><link>http://devplanet.com/blogs/brianr/archive/2008/12/15/async-coding-using-idisposable.aspx</link><pubDate>Mon, 15 Dec 2008 17:00:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:14089</guid><dc:creator>Brian Rudolph</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I recently watched this video on the PowerThreading library: &lt;a href="http://blogs.msdn.com/charlie/archive/2008/12/03/jeff-richter-video-on-asynchronous-programming-and-his-power-threading-library.aspx"&gt;http://blogs.msdn.com/charlie/archive/2008/12/03/jeff-richter-video-on-asynchronous-programming-and-his-power-threading-library.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is very interesting as Jeff Richter utilizes a strange behavior in the way the C# compiler works with IEnumerables to make a useful and easy-to-use async library.&amp;nbsp; His primary goal was to allow a website\service yield processing during I/O operations, which can provide for better scalability in your app tier.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;While this is quite interesting, I personally would avoid using strange compilation patterns to my advantage in an application.&amp;nbsp; Specifically because you have no assurance that the compiler will always do this as the language and subsequent compilers evolve.&amp;nbsp; What I was interested in was the mechanism for including asynchronous calls into code without using a complex series of callbacks.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Now, to be quite fair, Jeff&amp;#39;s implementation was an attempt to limit thread spawning, and context switches.&amp;nbsp; I am not going to account for this.&amp;nbsp; I am more interested in parrallel processing.&lt;/p&gt;
&lt;p&gt;Let me give you an example.&amp;nbsp; Take for instance a series of objects that the UI is going to take cues from and make subsequent database calls to retrieve extra data for.&amp;nbsp; A simple example is a treeview.&amp;nbsp; If I have a bunch of nodes in a tree and the UI requires that I display the child node or&amp;nbsp;items&amp;nbsp;count for each of these nodes. What you would generally do is loop through the objects and call the DB to retrieve the data,&amp;nbsp;and assign the UI components in one serial block of code.&amp;nbsp; The problem with this is that the database is more than likely capable of servicing the request for numerous nodes simultaneously, but in the UI we are implementing this serially.&amp;nbsp; If the tree structure is complex, and you are showing more than just a node count, it is plausible that each of these requests will take upward of 50ms.&amp;nbsp; If you have several dozen nodes being displayed this can easily add seconds to your response time.&lt;/p&gt;
&lt;p&gt;A serial block of code might look like this:&lt;/p&gt;
&lt;p&gt;&lt;table cellpadding="0" cellspacing="0" style="background-color:#f2f2f2;border:solid 1px #e5e5e5;width:100%;"&gt;
&lt;tr style="vertical-align:top;line-height:normal;"&gt;&lt;td&gt;&lt;pre style="overflow:scroll;margin:0px;padding:2px;padding-left:8px;"&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;TreeNodeCollection nodes &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; TreeNodeCollection();
&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;foreach&lt;/span&gt; (TreeNode node &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;in&lt;/span&gt; nodes)
{
     &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; objectCount &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; database.DoSomething((MyObject)node.Tag); &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//call the database&lt;/span&gt;
     node.Text &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; String.Format(&lt;span style="color:#666666;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&amp;quot;{0} ({1})&amp;quot;&lt;/span&gt;, node.Text, objectCount); &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//update the UI&lt;/span&gt;
 }&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Simple and clean, but slow.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Why not do all of these calls asynchronously, wait for all of the results to filter in, and then update the UI?&amp;nbsp; This should surely be faster than a serial operation.&amp;nbsp; Let&amp;#39;s say, we spawn&amp;nbsp;Math.Min(nodes.Count, 10)&amp;nbsp;threads to accomplish this&amp;nbsp;task.&amp;nbsp; So at a maximum, we will use 10 threads to do the work. If we have 20 nodes, it should take at the longest 2 times as long as the longest running call.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The usual issue with this is that it requires you to use several call-back methods, do complicated thread monitoring, and subsequently put the UI into a wait state until all of the external threads have finished.&amp;nbsp; Unfortunately there just is no simple way to do it.&lt;/p&gt;
&lt;p&gt;So I got to thinking, what construct can I use to signal an asynchronous block, that would prevent execution beyond it&amp;#39;s bounds until all the threads were done.&amp;nbsp; The answer, IDisposable.&amp;nbsp; If I created an IDisposable object and wrapped it in a &amp;quot;using&amp;quot; I could prevent the Dispose method from exiting until all the threads have finished.&lt;/p&gt;
&lt;p&gt;Utilizing the rest of my Threading objects, this should be fairly simple to accomplish, all I had to do was add a done flag to my workerbee:&lt;/p&gt;
&lt;p&gt;&lt;table cellpadding="0" cellspacing="0" style="background-color:#f2f2f2;border:solid 1px #e5e5e5;width:100%;"&gt;
&lt;tr style="vertical-align:top;line-height:normal;"&gt;&lt;td&gt;&lt;pre style="overflow:scroll;margin:0px;padding:2px;padding-left:8px;"&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; AsyncBlock : IDisposable
{


        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;long&lt;/span&gt; timeoutMS &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; 0;
        Dispatcher dispatcher &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; started &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;;

        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; AsyncBlock() : &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;(10) { }

        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; AsyncBlock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; timeoutSeconds) : &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;(timeoutSeconds, 5) { }

        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; AsyncBlock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; timeoutSeconds, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; threads) : &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; Dispatcher(threads), timeoutSeconds) { }

        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; AsyncBlock(Dispatcher dispatcher, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; timeoutSeconds)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dispatcher &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; dispatcher;
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.timeoutMS &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; timeoutSeconds &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;*&lt;/span&gt; 1000;
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkQueue &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; List&amp;lt;WorkerBee&amp;gt;();
        }


        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; IList&amp;lt;WorkerBee&amp;gt; WorkQueue
        {
            get;
            set;
        } 


       &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; IList&amp;lt;WorkerBee&amp;gt; GetWorkers()        
       {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; List&amp;lt;WorkerBee&amp;gt;(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkQueue);
        } 


        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; AddToQueue(WorkerBee bee)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkQueue.Add(bee);
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dispatcher.AddToQueue(bee);
            started &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;;
        }


        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Start()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;foreach&lt;/span&gt; (WorkerBee bee &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;in&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkQueue)
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (!bee.Done)
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dispatcher.AddToQueue(bee);


            started &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;;
        }


        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (!started &amp;amp;&amp;amp; WorkQueue.Count !&lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; 0)
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;throw&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; Exception(&lt;span style="color:#666666;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&amp;quot;Work was never started&amp;quot;&lt;/span&gt;);
            }


            System.Diagnostics.Stopwatch watch &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; System.Diagnostics.Stopwatch();
            watch.Start();
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; done &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;;

            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (!done)
            {
                done &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;;
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;foreach&lt;/span&gt; (WorkerBee bee &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;in&lt;/span&gt; WorkQueue)
                {
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (!(done &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; done &amp;amp;&amp;amp; bee.Done))
                        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;break&lt;/span&gt;;
                }
 


                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (watch.ElapsedMilliseconds &amp;gt; timeoutMS)
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;throw&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; TimeoutException(&lt;span style="color:#666666;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&amp;quot;Timeout elapsed&amp;quot;&lt;/span&gt;);
 
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (!done)
                    Thread.Sleep(1); &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;// wait 1ms to try again&lt;/span&gt;
            }
 
            watch.Stop();
        }
}


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; DatabaseWorkerBee&amp;lt;RefType, ReturnType&amp;gt; : AnyWorkerBee&amp;lt;Delegate&amp;gt;
{
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;delegate&lt;/span&gt; ReturnType DBDelegate();
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; DBDelegate dbDelegate;

        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; ReturnType ReturnValue
        {
            get;
            set;
        } 


        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; RefType ReferenceObject
        {
            get;
            set;
        } 


        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; DatabaseWorkerBee(RefType refObject, DBDelegate del)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.ReferenceObject &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; refObject;
            dbDelegate &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; del;
        } 


        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;protected&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;override&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; WorkStart()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;base&lt;/span&gt;.WorkStart();
 
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (dbDelegate !&lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;)
            {
                ReturnValue &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; dbDelegate();
            }
        }
    }


 &lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Alright, this is now a fairly simple implementation in&amp;nbsp; the UI:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;table cellpadding="0" cellspacing="0" style="background-color:#f2f2f2;border:solid 1px #e5e5e5;width:100%;"&gt;
&lt;tr style="vertical-align:top;line-height:normal;"&gt;&lt;td&gt;&lt;pre style="overflow:scroll;margin:0px;padding:2px;padding-left:8px;"&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;IList&amp;lt;WorkerBee&amp;gt; workers &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;;


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (AsyncBlock block &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; AsyncBlock(30, Math.Min(nodes.Count, 10))) &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;// do these async with a 30 second timeout&lt;/span&gt;
{
      &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;foreach&lt;/span&gt; (TreeNode o &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;in&lt;/span&gt; nodes)
      {
          TreeNode node &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; o; &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//must declare this in the loop, or you get the same object in every worker, this is a documented closure bug in the framework&lt;/span&gt;
          block.AddToQueue(
              &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; DatabaseWorkerBee&amp;lt;TreeNode, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt;&amp;gt;( node, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;delegate&lt;/span&gt; { &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/* Do Database Call Here using the node object*/&lt;/span&gt;; }));
       }


      workers &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; block.GetWorkers()


}&lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//using will not return until all workers have been processed.&lt;/span&gt;


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;foreach&lt;/span&gt; (WorkerBee worker &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;in&lt;/span&gt; workers)
{
      DatabaseWorkerBee&amp;lt;TreeNode, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt;&amp;gt; dbworker &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; worker &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;as&lt;/span&gt; DatabaseWorkerBee&amp;lt;TreeNode, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt;&amp;gt;;
      dbWorker.ReferenceObject.Text &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; String.Format(&lt;span style="color:#666666;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&amp;quot;{0} ({1})&amp;quot;&lt;/span&gt;, dbWorker.ReferenceObject.Text, dbWorker.ReturnValue); &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//update the UI&lt;/span&gt;
}


 &lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Woot!&amp;nbsp; All of the nodes are executed async, and all of the values are returned properly.&amp;nbsp; One thing to note, notice I am declaring a redundant TreeNode object inside the loop.&amp;nbsp; This is necessary, since we are using an anonymous method inside of the loop.&amp;nbsp; If we were to just reference the &amp;quot;o&amp;quot; in the iterator, we would get the same object passed to each anonymous method.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;My Threading Objects can be found here: &lt;a href="http://devplanet.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/brianr.Code+Snippets/ThreadingLib.zip"&gt;ThreadLib.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[Edit]&lt;br /&gt;After further review and testing this code works quite well, except in the instance of windows authenticated database connections.&amp;nbsp; Because we are spawning new threads, and your security context is thread based, all of the subsequent database calls were made using the applications default user.&amp;nbsp; This isn&amp;#39;t a problem in Windows UI&amp;#39;s but in Web apps this is not good.&amp;nbsp; It could be as simple as setting the new threads to the same security context as the spawning thread, but I&amp;#39;m not sure I want that to happen for every thread.&amp;nbsp; I will work this out and do an update.&lt;/p&gt;
&lt;p&gt;I have worked this security context issue out. If anyone is interested in it, email me.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=14089" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/brianr/archive/tags/Threading/default.aspx">Threading</category><category domain="http://devplanet.com/blogs/brianr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://devplanet.com/blogs/brianr/archive/tags/Async/default.aspx">Async</category><category domain="http://devplanet.com/blogs/brianr/archive/tags/IDisposable/default.aspx">IDisposable</category></item><item><title>PASS Community Summit Recap</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2008/12/03/pass-community-summit-recap.aspx</link><pubDate>Thu, 04 Dec 2008 01:18:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:13966</guid><dc:creator>Chuck</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;This year was my last year as a member of the leadership of the Professional Association for SQL Server.&amp;nbsp; I will still be involved with the organization, but will be rolling off of the Board of Directors at the end of my 2 year term in December.&lt;/p&gt;
&lt;p&gt;That made this event a little different for me.&amp;nbsp; I&amp;#39;ve been at 9 of the 10 US PASS conferences - the only one that&amp;nbsp;I missed was the first one.&amp;nbsp; I&amp;#39;ve attended them in a variety of capacities - speaker, board member and even general attendee.&lt;/p&gt;
&lt;p&gt;This year was the largest PASS conference ever.&amp;nbsp; It included three amazing keynotes.&amp;nbsp; My favorite was given by Dr. David DeWitt.&amp;nbsp; Dr. DeWitt is a Technical Fellow with the Gray Systems Lab in Madison, WI (which is located just an hour&amp;nbsp;down the road from me).&amp;nbsp; The keynote contained no marketing - the entire presentation was about the theory and research that goes into building high performance scalable database systems.&amp;nbsp; It was one of the best technical lectures that I have ever attended.&lt;/p&gt;
&lt;p&gt;There were over 120 technical sessions at this conference - and I did manage to make it to a few of them.&amp;nbsp; One of my goals for the conference was to meet as many Microsoft employees as I could, and I think I did quite well for myself.&amp;nbsp; I also served as the moderator for a panel debate on the pros and cons of NULL.&amp;nbsp; The panel consisted of 5 SQL Server MVPs, and one guy&amp;nbsp;who should be one.&amp;nbsp; The session was well attended and the debate got quite heated at times.&amp;nbsp; Who would have thought that a debate about nothing would be so well received?&lt;/p&gt;
&lt;p&gt;Next year&amp;#39;s PASS conference is again going to be held in Seattle.&amp;nbsp; The dates are November 3 - 6, 2009.&amp;nbsp; I encourage anyone who is interested in the best SQL Server education for the money to attend.&lt;/p&gt;
&lt;p&gt;That&amp;#39;s it for now...got to get back to installing MOSS and PerformancePoint - but that&amp;#39;s another blog post entirely.&lt;/p&gt;
&lt;p&gt;Chuck&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=13966" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/PASS/default.aspx">PASS</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/MVP/default.aspx">MVP</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Gray+Systems+Lab/default.aspx">Gray Systems Lab</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/NULL/default.aspx">NULL</category></item><item><title>More Threading Goodness!</title><link>http://devplanet.com/blogs/brianr/archive/2008/11/26/more-threading-goodness.aspx</link><pubDate>Wed, 26 Nov 2008 20:48:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:13616</guid><dc:creator>Brian Rudolph</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Threading - I write about it a lot, even though i would consider myself somewhat of a rookie when it comes to threading complexities.&lt;/p&gt;
&lt;p&gt;One of the challenges we often find when trying to incorporate threading into applications is managing work units, thread pools, and queues.&amp;nbsp; What I&amp;#39;ve ended up doing is writing a few helpers to accommodate just these things.&lt;/p&gt;
&lt;p&gt;To start, we need to manage a pool of available thread resources.&amp;nbsp; This pool needs to have a limit, and needs to be able to generate threads on the fly if necessary.&amp;nbsp; However, the need for resource pools is not limited to threading.&amp;nbsp; Consider the scenario where you have a web service of some sort, being WSE, FTP HTTP whatever.&amp;nbsp; There is a lot of overhead in opening and handshaking for these connections.&amp;nbsp; If I had say a list of 100k files I needed to upload, and wanted to do that asynchronously, I wouldn&amp;#39;t want to throw away the connection after every upload.&amp;nbsp; So I need to do simple connection pooling.&amp;nbsp; But I don&amp;#39;t want to open 10 connections immediately if I am only going to need 2 either, so this pool needs to be dynamic.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;To even start writing a pool, we need some sort of queuing class for resource storage, and in the threaded world, this needs to be thread safe.&lt;/p&gt;
&lt;p&gt;So a simple wrapper may look something like this:&lt;/p&gt;
&lt;p&gt;&lt;table cellpadding="0" cellspacing="0" style="background-color:#f2f2f2;border:solid 1px #e5e5e5;width:100%;"&gt;
&lt;tr style="vertical-align:top;line-height:normal;"&gt;&lt;td&gt;&lt;pre style="overflow:scroll;margin:0px;padding:2px;padding-left:8px;"&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; ThreadSafeQueue&amp;lt;T&amp;gt;
    {
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//This is the internal queue that we are wrapping&lt;/span&gt;
        Queue&amp;lt;T&amp;gt; queue &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; Queue&amp;lt;T&amp;gt;();
 
        [NonSerialized]
        ReaderWriterLockSlim objLock &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; Locks.GetLockInstance(LockRecursionPolicy.NoRecursion); &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//setup the lock;&lt;/span&gt;
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; Count
        {
            get
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.objLock))
                {
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.queue.Count;
                }
            }
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Clear()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.objLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.queue.Clear(); ;
            }
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; Contains(T item)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.objLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.queue.Contains(item);
            }
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; TryDequeue(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;out&lt;/span&gt; T obj)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.objLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.queue.Count !&lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; 0)
                {
                    obj &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Dequeue();
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;;
                }
            }
 
            obj &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;default&lt;/span&gt;(T);
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;;
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; T Dequeue()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.objLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.queue.Dequeue();
            }
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Enqueue(T item)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.objLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.queue.Enqueue(item);
            }
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; T Peek()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.objLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.queue.Peek();
            }
        }
    }&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Then we can move on to the Resource Pool, which we want to be generic so that it can serve up any kind of resource, be it a thread, a web service connection, a widget of any sort.&lt;/p&gt;
&lt;p&gt;&lt;table cellpadding="0" cellspacing="0" style="background-color:#f2f2f2;border:solid 1px #e5e5e5;width:100%;"&gt;
&lt;tr style="vertical-align:top;line-height:normal;"&gt;&lt;td&gt;&lt;pre style="overflow:scroll;margin:0px;padding:2px;padding-left:8px;"&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; ResourcePool&amp;lt;T&amp;gt; : IDisposable
        where T : &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt;
    {
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;event&lt;/span&gt; EventHandler CreatedResource;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;delegate&lt;/span&gt; T CreateResourceDelegate();
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;delegate&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; CanReuseResourceDelegate(T obj);
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; ResourcePool(CreateResourceDelegate creatorDelegate, CanReuseResourceDelegate checkerDelegate)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.MaxResourceCount &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; 10;
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.IterationTimeout &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; 5;
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.MaxRetry &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; 100;
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Creator &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; creatorDelegate;
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.CheckResource &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; checkerDelegate;
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; CreateResourceDelegate Creator { get; set; }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; CanReuseResourceDelegate CheckResource { get; set; }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Retreives a resource from the pool.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; T Get()
        {
            T obj &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;;
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;try&lt;/span&gt;
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; tries &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; 0;
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (obj == &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.MaxRetry == 0 || tries++ &amp;lt;= &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.MaxRetry))
                {
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (Queue.Count == 0)
                    {
                        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.MaxResourceCount == 0 || (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.MaxResourceCount &amp;gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.ActiveResourceCount))
                        {
                            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Creator == &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;)
                                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;throw&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; NullReferenceException(&lt;span style="color:#666666;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&amp;quot;Unable to create new Resource Instance&amp;quot;&lt;/span&gt;);
 
                            obj &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Creator();
                            FireEvent(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;ref&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.CreatedResource);
                        }
                        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;else&lt;/span&gt;
                        {
                            Thread.Sleep(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.IterationTimeout); &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;// wait for one to become available if we can&amp;#39;t create one.&lt;/span&gt;
                        }
                    }
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;else&lt;/span&gt;
                    {
                        obj &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; Queue.Dequeue();
                    }
                }
            }
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;finally&lt;/span&gt;
            {
                Interlocked.Increment(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;ref&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._ActiveResourceCount);
            }
 
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (obj == &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;)
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;throw&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; NullReferenceException(&lt;span style="color:#666666;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&amp;quot;Unable to retrieve Resource Instance&amp;quot;&lt;/span&gt;);
 
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; obj;
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Returns a resource to the pool.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;obj&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Release(T obj)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;try&lt;/span&gt;
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.MaxResourceCount == 0 || Queue.Count &amp;lt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.MaxResourceCount)
                {
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.CheckResource == &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt; || &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.CheckResource(obj))
                    {
                        Queue.Enqueue(obj);
                    }
                }
            }
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;finally&lt;/span&gt;
            {
               Interlocked.Decrement(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;ref&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._ActiveResourceCount); &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//decrement counter so we know we can reuse the resource.&lt;/span&gt;
            }
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; _ActiveResourceCount;
         
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is the maximum number of resources the pool will hold and subsequently attempt to create.  Default is 10.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Set to 0 enables no limit.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; MaxResourceCount { get; set; }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is the maximum number of times the pool will look for or attempt to create a resource.  Default is 100.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Set to 0 enables no limit.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; MaxRetry { get; set; }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is the length of time(in milliseconds) that the pool will wait between tries to get a resource. Default is 5ms.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; IterationTimeout { get; set; }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; ThreadSafeQueue&amp;lt;T&amp;gt; Queue
        {
            get { &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Queue; }
        }&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;readonly&lt;/span&gt; ThreadSafeQueue&amp;lt;T&amp;gt; _Queue &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ThreadSafeQueue&amp;lt;T&amp;gt;();
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; FireEvent(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;ref&lt;/span&gt; EventHandler targetEvent)
        {
            Eventing.FireEvent(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;ref&lt;/span&gt; targetEvent, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;);
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; disposing)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (disposing)
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Queue.Clear();
            }
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Dispose(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;);
        }
    }&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;I know I am tearing through this quickly, but it&amp;#39;s a lot to explain.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Now we need to have some sort of managed work unit that the thread can work on.&amp;nbsp; We want it&amp;#39;s work unit to be generic and should be easily derived from:&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0" style="background-color:#f2f2f2;border:solid 1px #e5e5e5;width:100%;"&gt;
&lt;tr style="vertical-align:top;line-height:normal;"&gt;&lt;td&gt;&lt;pre style="overflow:scroll;margin:0px;padding:2px;padding-left:8px;"&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; WorkerBee
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; WorkerBee() { }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Start();
    }
 
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; WorkerBee&amp;lt;T&amp;gt; : WorkerBee
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; T WorkUnit { get; set; }
    }
 
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This worker can be used as it.  Subscribe to the WorkBegan and WorkFinished events to inject logic.&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; AnyWorkerBee&amp;lt;T&amp;gt; : WorkerBee&amp;lt;T&amp;gt;
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;delegate&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; WorkerEventHandler(WorkerBee&amp;lt;T&amp;gt; sender);
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;event&lt;/span&gt; WorkerEventHandler WorkBegan;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;event&lt;/span&gt; WorkerEventHandler WorkFinished;
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;protected&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; OnWorkBegan()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkBegan !&lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;)
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkBegan(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;);
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;protected&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; OnWorkFinished()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkFinished !&lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;)
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkFinished(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;);
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;protected&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; WorkStart()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.OnWorkBegan();
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;protected&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; WorkFinish()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.OnWorkBegan();
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; DoWork() { }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;override&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Start()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkStart();
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.DoWork();
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkFinish();
        }
    }&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Now we can look at the actual dispatcher, we need some way to add work to a queue, have it spawn a thread if it has any left, and then execute the work.&amp;nbsp; One of the tricky things was to make sure the dispatcher thread was not ALWAYS running.&amp;nbsp; It would start itself up anytime work was added, continue running and waiting until it&amp;#39;s work queue was empty, then shut down.&amp;nbsp; Every subsequent addition to the queue would ensure that the dispatcher was still running.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0" style="background-color:#f2f2f2;border:solid 1px #e5e5e5;width:100%;"&gt;
&lt;tr style="vertical-align:top;line-height:normal;"&gt;&lt;td&gt;&lt;pre style="overflow:scroll;margin:0px;padding:2px;padding-left:8px;"&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt; 
&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; Dispatcher : IDisposable
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; Dispatcher(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; maxThreadCount)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Threads &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ResourcePool&amp;lt;Thread&amp;gt;(
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ResourcePool&amp;lt;Thread&amp;gt;.CreateResourceDelegate(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.CreateThread),
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ResourcePool&amp;lt;Thread&amp;gt;.CanReuseResourceDelegate(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.ValidateThread));
 
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Threads.MaxRetry &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; 0;
 
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkQueue &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ThreadSafeQueue&amp;lt;WorkerBee&amp;gt;();
 
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Threads.MaxResourceCount &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; maxThreadCount;
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.EnsureDispatch(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;); &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;// setup the dispatcher&lt;/span&gt;
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Call this to stop the dispatcher&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Abort()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.AbortDispatch &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;;
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Call this to pause the dispatcher&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Pause()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.AbortDispatch &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;;
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Call this to resume the dispatcher&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Resume()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.AbortDispatch)
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.AbortDispatch &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;;
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.EnsureDispatch();
            }
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Set this to prevent the dispatcher from spawning threads.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; AbortDispatch
        {
            get;
            set;
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is the thread that will dispatch work to other threads.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; Thread DispatchThread
        {
            get;
            set;
        }&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;object&lt;/span&gt; _DispatcherLock &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; Object();
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This will make sure that the Dispatcher is active and running.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; EnsureDispatch()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.EnsureDispatch(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;);
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This will make sure that the Dispatcher is active and running.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; EnsureDispatch(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; start)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;lock&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._DispatcherLock)
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.DispatchThread == &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt; || &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.DispatchThread.ThreadState == ThreadState.Stopped)
                {
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.DispatchThread &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; Thread(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ThreadStart(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.FireThread));
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.DispatchThread.IsBackground &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;;
                }
 
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (start &amp;amp;&amp;amp; ((&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.DispatchThread.ThreadState &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;|&lt;/span&gt; ThreadState.Unstarted) == &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.DispatchThread.ThreadState))
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.DispatchThread.Start();
            }
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is a required callback for the Resource pool.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;obj&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; ValidateThread(Thread obj)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;; &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//never reuse threads&lt;/span&gt;
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is the method that the resource pool will call to get a new thread to work with.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; Thread CreateThread()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; Thread(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ParameterizedThreadStart(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.DispatchWork));
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// The function starts the work on a new thread.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; DispatchWork(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;object&lt;/span&gt; state)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;try&lt;/span&gt;
            {
                WorkerBee work &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; state &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;as&lt;/span&gt; WorkerBee;
 
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (work !&lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;)
                    work.Start();
            }
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;finally&lt;/span&gt;
            {
                &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//Give the thread back.&lt;/span&gt;
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Threads.Release(Thread.CurrentThread);
            }
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This puts work on the queue and starts the dispatcher&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;obj&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; AddToQueue(WorkerBee obj)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkQueue.Enqueue(obj);
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.EnsureDispatch();
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; GetQueueLength()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkQueue.Count;
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is the callback that the dispatcher thread calls.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// It will initialize a new thread from the pool and start work&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; FireThread()
        {
            WorkerBee work &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;;
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (!AbortDispatch &amp;amp;&amp;amp; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkQueue.TryDequeue(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;out&lt;/span&gt; work))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (work !&lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;)
                {
                    Thread thread &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Threads.Get();
                    
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (!AbortDispatch) &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;// check again&lt;/span&gt;
                        thread.Start(work);
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;else&lt;/span&gt;
                        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Threads.Release(Thread.CurrentThread);
                }
            }
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is the queue of stuff to be done.&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; ThreadSafeQueue&amp;lt;WorkerBee&amp;gt; WorkQueue
        {
            get;
            set;
        }
 
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Simple resource pool filled with threads&lt;/span&gt;
        &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; ResourcePool&amp;lt;Thread&amp;gt; Threads
        {
            get;
            set;
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; disposing)
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (disposing)
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.WorkQueue.Clear();
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Threads.Dispose();
            }
        }
 
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose()
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.Dispose(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;);
        }
    }&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devplanet.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/brianr.Code+Snippets/ThreadingDemo.zip"&gt;ThreadingDemo.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Download the code and test project and try it for yourself.&amp;nbsp; I will say that this is fairly experimental, although I have been using it for quite a few things and have experienced no issues.&amp;nbsp; One of the major things I have used it for is the cache scavenger in my Factory caching model and it seems to work great.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=13616" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/brianr/archive/tags/Threading/default.aspx">Threading</category><category domain="http://devplanet.com/blogs/brianr/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Silverlight 2 XAML Binding and Custom / Core Dependency Properties</title><link>http://devplanet.com/blogs/justice/archive/2008/11/23/silverlight-2-xaml-binding-and-custom-core-dependency-properties.aspx</link><pubDate>Sun, 23 Nov 2008 18:14:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:13468</guid><dc:creator>David Justice</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;The basic scenario is as follows: &amp;nbsp;I have done quite a bit of WPF programming in the past (since back when it was WinFx). &amp;nbsp;I feel pretty damn good about the bindings in WPF, and I feel like I have wrapped my head around binding and dependency properties pretty well. &amp;nbsp;So, I thought when I decided to write Silverlight 2 apps rather than straight to the vein, white horse, WPF apps, it would be a very similar feeling. &amp;nbsp;The feeling was abruptly interrupted by the evilness of the ElementName Binding param. &amp;nbsp;For those of you who have spent time writing WPF apps, you will know the joy of binding element properties to each other and having no problems. &amp;nbsp;It&amp;#39;s easy to take such things for granted.&lt;/p&gt;...(&lt;a href="http://devplanet.com/blogs/justice/archive/2008/11/23/silverlight-2-xaml-binding-and-custom-core-dependency-properties.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://devplanet.com/aggbug.aspx?PostID=13468" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/justice/archive/tags/Silverlight+2/default.aspx">Silverlight 2</category><category domain="http://devplanet.com/blogs/justice/archive/tags/Binding/default.aspx">Binding</category><category domain="http://devplanet.com/blogs/justice/archive/tags/Dependency+Property/default.aspx">Dependency Property</category></item><item><title>Silver Lining for Windows Azure -- Silverlight 2 Sample Hosted in Azure</title><link>http://devplanet.com/blogs/justice/archive/2008/11/08/silver-lining-for-windows-azure-silverlight-2-sample-hosted-in-azure.aspx</link><pubDate>Sat, 08 Nov 2008 16:00:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:12331</guid><dc:creator>David Justice</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I melded an Azure Web Role project and the Silverlight Toolkit sample to give you guys a quick download, so you can play with them together.&amp;nbsp; I hope you like it, and I hope it helps you explore some of the new technology.&amp;nbsp; I call it&amp;nbsp;&lt;a target="_blank" title="SiverLining.zip" href="/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/justice/SilverLining.zip"&gt;SilverLining&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;...(&lt;a href="http://devplanet.com/blogs/justice/archive/2008/11/08/silver-lining-for-windows-azure-silverlight-2-sample-hosted-in-azure.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://devplanet.com/aggbug.aspx?PostID=12331" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/justice/archive/tags/Azure/default.aspx">Azure</category><category domain="http://devplanet.com/blogs/justice/archive/tags/Windows+Azure/default.aspx">Windows Azure</category><category domain="http://devplanet.com/blogs/justice/archive/tags/Silverlight+Toolkit/default.aspx">Silverlight Toolkit</category><category domain="http://devplanet.com/blogs/justice/archive/tags/Silverlight+2/default.aspx">Silverlight 2</category></item><item><title>Unique Identifier Flat File Import with SSIS</title><link>http://devplanet.com/blogs/justice/archive/2008/11/07/unique-identifier-flat-file-import-with-ssis.aspx</link><pubDate>Fri, 07 Nov 2008 16:44:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:12307</guid><dc:creator>David Justice</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This morning I found myself wrestling with SSIS to convert a string from a flat file to a unique identifier via a Data Flow inside of an SSIS package. &amp;nbsp;I figured this would be a rather trivial case&amp;nbsp;(the midget was kicking my ass!). &amp;nbsp;I use guids all over for application development and for database keys. &amp;nbsp;They are very useful, and very dependable. &amp;nbsp;Here is a line from my flat file:&lt;/p&gt;
&lt;p&gt;61898d4c-3a1b-4736-9a36-eb90a23322e0|:|10/13/2008 11:59:58 PM|:|74afebfe-9523-4977-b5f6-5154b6c91211&lt;/p&gt;
&lt;p&gt;Anyone see anything wrong with this? &amp;nbsp;I didn&amp;#39;t see anything wrong, outside of the silly |:| delimiter (I don&amp;#39;t want to get started on that &amp;lt;rant/&amp;gt; &amp;lt;--- rant with no content!).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;...(&lt;a href="http://devplanet.com/blogs/justice/archive/2008/11/07/unique-identifier-flat-file-import-with-ssis.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://devplanet.com/aggbug.aspx?PostID=12307" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/justice/archive/tags/GUID/default.aspx">GUID</category><category domain="http://devplanet.com/blogs/justice/archive/tags/SQL/default.aspx">SQL</category><category domain="http://devplanet.com/blogs/justice/archive/tags/SSIS/default.aspx">SSIS</category><category domain="http://devplanet.com/blogs/justice/archive/tags/Unique+Identfier/default.aspx">Unique Identfier</category></item><item><title>MetaTable Expression Builder for Fetching Any Object Via Collection of Primary Keys</title><link>http://devplanet.com/blogs/justice/archive/2008/11/04/metatable-expression-builder-for-fetching-any-object-via-collection-of-primary-keys.aspx</link><pubDate>Tue, 04 Nov 2008 14:53:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:12199</guid><dc:creator>David Justice</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Basically, I wanted to build a method that gets an object from a data context whatever the primary key may look like, and whatever type that object may be. &amp;nbsp;I wrote this code a little while ago when I was exploring the DynamicData libs. &amp;nbsp;I was checking out some of the code in the libs, and noticed a very slick way one of devs was building expressions to grab back a data item based on a single key ID. &amp;nbsp;I thought the idea of building up the expression completely ROCKED, but I wanted to expand it out to include composite primary keys. &amp;nbsp;Below is my implementation of the composite primary key object fetcher. &amp;nbsp;Hopefully, it will make your life a little easier.&lt;/p&gt;...(&lt;a href="http://devplanet.com/blogs/justice/archive/2008/11/04/metatable-expression-builder-for-fetching-any-object-via-collection-of-primary-keys.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://devplanet.com/aggbug.aspx?PostID=12199" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/justice/archive/tags/MetaModel/default.aspx">MetaModel</category><category domain="http://devplanet.com/blogs/justice/archive/tags/Expressions/default.aspx">Expressions</category><category domain="http://devplanet.com/blogs/justice/archive/tags/Expression+Building/default.aspx">Expression Building</category><category domain="http://devplanet.com/blogs/justice/archive/tags/Linq/default.aspx">Linq</category><category domain="http://devplanet.com/blogs/justice/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Windows Azure and _NOT_ SQLExpress</title><link>http://devplanet.com/blogs/justice/archive/2008/11/02/windows-azure-and-not-sqlexpress.aspx</link><pubDate>Sun, 02 Nov 2008 17:37:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:12196</guid><dc:creator>David Justice</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;I&amp;#39;ve been very excited recently by the release of Windows Azure, and rest of the Microsoft suite of cloud based services. &amp;nbsp;I downloaded all of the sdk&amp;#39;s, signed up for all the invitation tokens I could, and began writing code. &amp;nbsp;The Visual Studio templates for Windows Azure projects makes getting your first Azure project up and running super simple. &amp;nbsp;I did run into one issues with the project templates setting up my first project.&lt;/p&gt;...(&lt;a href="http://devplanet.com/blogs/justice/archive/2008/11/02/windows-azure-and-not-sqlexpress.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://devplanet.com/aggbug.aspx?PostID=12196" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/justice/archive/tags/Azure/default.aspx">Azure</category><category domain="http://devplanet.com/blogs/justice/archive/tags/SQLExpress/default.aspx">SQLExpress</category><category domain="http://devplanet.com/blogs/justice/archive/tags/Windows+Azure/default.aspx">Windows Azure</category><category domain="http://devplanet.com/blogs/justice/archive/tags/Cloud+Computing/default.aspx">Cloud Computing</category></item><item><title>Work Harder</title><link>http://devplanet.com/blogs/brianr/archive/2008/10/21/work-harder.aspx</link><pubDate>Tue, 21 Oct 2008 15:26:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:12160</guid><dc:creator>Brian Rudolph</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;Work Harder!&amp;nbsp; That is a statement I find myself repeating daily.&amp;nbsp; People often wonder what makes one person better at a certain task than others.&amp;nbsp; There is a truly simple answer, practice.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Natural ability is a myth. &amp;nbsp;With the exception of physical limitations, all ability is gained through practice.&amp;nbsp; No infant is born with the innate ability to walk.&amp;nbsp; No musician picks up an instrument for the first time and performs a flawless number.&amp;nbsp; Everything &amp;lsquo;great&amp;#39; is preceded by countless not-so-great attempts.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The human race is a term that to some is a simple definition of our status as homosapiens.&amp;nbsp; To me, it is a bit more literal.&amp;nbsp; I recognize that there are billions of people in this world, all of whom want the same things I do.&amp;nbsp; What sets certain individuals apart from the pack is their willingness to work harder than the rest.&amp;nbsp; So for me, it&amp;#39;s the race of humans.&amp;nbsp; Who wants to work harder?&amp;nbsp; Who wants to spend that extra effort day after day to be the best at what they do.&amp;nbsp; Someone who doesn&amp;#39;t work as hard as I do does not deserve the same things I deserve, just as I do not deserve the same benefits of the people who work harder than I am willing to.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I hear complaints from people about the state of their lives, every argument of which never focuses on their lack of effort.&amp;nbsp; It is always the result of some innocuous outside influence.&amp;nbsp; Bunk.&amp;nbsp; People who work hard, achieve more.&amp;nbsp; Good things happen to good people who work hard.&amp;nbsp; Being good isn&amp;#39;t enough.&amp;nbsp; There are lots of &amp;quot;good&amp;quot; people, if the definition of &amp;quot;good&amp;quot; can be simplified to &amp;quot;not being bad&amp;quot;.&amp;nbsp; Spend a few more hours with your face buried in a book rather than a pint of beer.&amp;nbsp; Unless, of course, your goal is to be the best drinker on earth.&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Everything that has gone right in my life happened to me when I went the extra mile.&amp;nbsp; Every real accomplishment didn&amp;#39;t come from the 8 to 5 daily grind.&amp;nbsp; Good things happened during the hundred-hour weeks of work.&amp;nbsp; Times when 8 to 5 wouldn&amp;#39;t have been enough to get the job done, allowing the opportunity to pass right by.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;There have been many times I have explained to people that epiphanies have come to me in my sleep.&amp;nbsp; Though I was not lying, this is not a result of me having some abnormal super power.&amp;nbsp; It is a result of me wrapping my mind so deeply around a problem that I am consumed by it even during my few hours of sleep.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I like to think that everything that has happened to me in my life, I&amp;#39;ve earned.&amp;nbsp; This, of course, includes all of the bad things.&amp;nbsp; For many years my interests were simply in having fun, so my career took a nose-dive.&amp;nbsp; Then I focused entirely on work which destroyed countless relationships, as well as my physical health. So while balance has become important, I have recognized that&amp;nbsp;every decision&amp;nbsp;comes with consequences;&amp;nbsp;consequences which I hope to never complain about.&lt;/p&gt;
&lt;p&gt;People make choices in their lives.&amp;nbsp; If your choice is to pursue a career or path in your life that will never financially stabilize, you have no right to complain about finances.&amp;nbsp; You have chosen to sacrifice financial success for your love or interest in what it is you do.&amp;nbsp; It is not society&amp;#39;s responsibility to fill in for your financial woes.&amp;nbsp; If you choose to sacrifice your personal life for professional glory, then do not cry about your lack of intimacy.&amp;nbsp; You chose that path.&amp;nbsp; Just realize that everything requires hard work.&amp;nbsp; Even if an individual&amp;#39;s goal in life is to be the best parent their child could have, then they must work for it.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;This is not to say that I am better or worse than anyone else in this world.&amp;nbsp; What I am attempting to say is that I take responsibility for what happens in my life.&amp;nbsp; I will not give up, I will not rest until I am the best I can be at what I do, regardless of what this life throws at me.&amp;nbsp; The best I can be at anything will require a lifetime of effort.&amp;nbsp; So I suppose it is a valid assumption to say that I will only achieve this in the moment immediately before my death.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I truly wish more people would take responsibility for their lives.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=12160" width="1" height="1"&gt;</description></item><item><title>Thread Safe Dictionary Update</title><link>http://devplanet.com/blogs/brianr/archive/2008/09/29/thread-safe-dictionary-update.aspx</link><pubDate>Mon, 29 Sep 2008 16:14:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:12123</guid><dc:creator>Brian Rudolph</dc:creator><slash:comments>16</slash:comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For those of you that have read my post about the Thread Safe Dictionary, I have a few updates.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;In recent months, I have done a ridiculous amount of multi-threaded work.&amp;nbsp; This has forced me to expand my threading libraries.&amp;nbsp; One of the primary objects that required changes\fixes was my dictionary.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The dictionary uses ReaderWriterLockSlim locks.&amp;nbsp; These are clean, lightweight locks that MS has provided.&amp;nbsp; Most importantly, they allow upgradeable read locks.&amp;nbsp; I now use simple IDisposable locking wrappers.&amp;nbsp; This allows us to use the &amp;quot;using&amp;quot; syntax to ensure lock releases.&lt;/p&gt;
&lt;p&gt;It is important to note that no safe dictionary can provide safe inserts without the caller forcing a lock.&amp;nbsp; This is because by the time you check for the existence of an object and then insert it, it may have been inserted by another thread.&amp;nbsp; The only way to prevent this is by doing a &amp;quot;blind&amp;quot; merge.&amp;nbsp; The reason&amp;nbsp;I call it blind, is that when you do a merge, we check for existence, and do a replace\insert within the scope of a single write lock.&amp;nbsp; This means you cannot control which objects get replaced in the dictionary.&amp;nbsp; This is rarely important in caching situations.&lt;/p&gt;
&lt;p&gt;&lt;table cellpadding="0" cellspacing="0" style="background-color:#f2f2f2;border:solid 1px #e5e5e5;width:100%;"&gt;
&lt;tr style="vertical-align:top;line-height:normal;"&gt;&lt;td&gt;&lt;pre style="overflow:scroll;margin:0px;padding:2px;padding-left:8px;"&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; System;
&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; System.Collections;
&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; System.Threading;


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;interface&lt;/span&gt; IThreadSafeDictionary&amp;lt;TKey, TValue&amp;gt; : IDictionary&amp;lt;TKey, TValue&amp;gt;
{
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Merge is similar to the SQL merge or upsert statement.  &lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;key&amp;quot;&amp;gt;Key to lookup&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;newValue&amp;quot;&amp;gt;New Value&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; MergeSafe(TKey key, TValue newValue);


    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is a blind remove. Prevents the need to check for existence first.&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;key&amp;quot;&amp;gt;Key to Remove&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; RemoveSafe(TKey key);
}


[Serializable]
&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; ThreadSafeDictionary&amp;lt;TKey, TValue&amp;gt; : IThreadSafeDictionary&amp;lt;TKey, TValue&amp;gt;
{
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//This is the internal dictionary that we are wrapping&lt;/span&gt;
    IDictionary&amp;lt;TKey, TValue&amp;gt; dict &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; Dictionary&amp;lt;TKey, TValue&amp;gt;();


    [NonSerialized]
    ReaderWriterLockSlim dictionaryLock &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; Locks.GetLockInstance(LockRecursionPolicy.NoRecursion); &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//setup the lock;&lt;/span&gt;


    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is a blind remove. Prevents the need to check for existence first.&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;key&amp;quot;&amp;gt;Key to remove&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; RemoveSafe(TKey key)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.ContainsKey(key))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
                {
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Remove(key);
                }
            }
        }
    }


    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Merge does a blind remove, and then add.  Basically a blind Upsert.  &lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;key&amp;quot;&amp;gt;Key to lookup&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;newValue&amp;quot;&amp;gt;New Value&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; MergeSafe(TKey key, TValue newValue)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock)) &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;// take a writelock immediately since we will always be writing&lt;/span&gt;
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.ContainsKey(key))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Remove(key);
            }


            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Add(key, newValue);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; Remove(TKey key)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Remove(key);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; ContainsKey(TKey key)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.ContainsKey(key);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; TryGetValue(TKey key, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;out&lt;/span&gt; TValue value)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.TryGetValue(key, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;out&lt;/span&gt; value);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; TValue &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;[TKey key]
    {
        get
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict[key];
            }
        }
        set
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict[key] &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; value;
            }
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;TKey&amp;gt; Keys
    {
        get
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; List&amp;lt;TKey&amp;gt;(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Keys);
            }
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;TValue&amp;gt; Values
    {
        get
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; List&amp;lt;TValue&amp;gt;(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Values);
            }
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Clear()
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Clear();
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; Count
    {
        get
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Count;
            }
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; Contains(KeyValuePair&amp;lt;TKey, TValue&amp;gt; item)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Contains(item);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Add(KeyValuePair&amp;lt;TKey, TValue&amp;gt; item)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Add(item);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Add(TKey key, TValue value)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Add(key, value);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; Remove(KeyValuePair&amp;lt;TKey, TValue&amp;gt; item)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Remove(item);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; CopyTo(KeyValuePair&amp;lt;TKey, TValue&amp;gt;[] array, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; arrayIndex)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.CopyTo(array, arrayIndex);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; IsReadOnly
    {
        get
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.IsReadOnly;
            }
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; IEnumerator&amp;lt;KeyValuePair&amp;lt;TKey, TValue&amp;gt;&amp;gt; GetEnumerator()
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;throw&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; NotSupportedException(&lt;span style="color:#666666;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&amp;quot;Cannot enumerate a threadsafe dictionary.  Instead, enumerate the keys or values collection&amp;quot;&lt;/span&gt;);
    }


    IEnumerator IEnumerable.GetEnumerator()
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;throw&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; NotSupportedException(&lt;span style="color:#666666;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&amp;quot;Cannot enumerate a threadsafe dictionary.  Instead, enumerate the keys or values collection&amp;quot;&lt;/span&gt;);
    }
}


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; Locks
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; GetReadLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (!lockAcquired)
            lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; locks.TryEnterUpgradeableReadLock(1);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; GetReadOnlyLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (!lockAcquired)
            lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; locks.TryEnterReadLock(1);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; GetWriteLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (!lockAcquired)
            lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; locks.TryEnterWriteLock(1);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; ReleaseReadOnlyLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (locks.IsReadLockHeld)
            locks.ExitReadLock();
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; ReleaseReadLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (locks.IsUpgradeableReadLockHeld)
            locks.ExitUpgradeableReadLock();
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; ReleaseWriteLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (locks.IsWriteLockHeld)
            locks.ExitWriteLock();
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; ReleaseLock(ReaderWriterLockSlim locks)
    {
        ReleaseWriteLock(locks);
        ReleaseReadLock(locks);
        ReleaseReadOnlyLock(locks);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; ReaderWriterLockSlim GetLockInstance()
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; GetLockInstance(LockRecursionPolicy.SupportsRecursion);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; ReaderWriterLockSlim GetLockInstance(LockRecursionPolicy recursionPolicy)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReaderWriterLockSlim(recursionPolicy);
    }
}


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; BaseLock : IDisposable
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;protected&lt;/span&gt; ReaderWriterLockSlim _Locks;


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; BaseLock(ReaderWriterLockSlim locks)
    {
        _Locks &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; locks;
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose();
}


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; ReadLock : BaseLock
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; ReadLock(ReaderWriterLockSlim locks)
        : &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;base&lt;/span&gt;(locks)
    {
        Locks.GetReadLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;override&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose()
    {
        Locks.ReleaseReadLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }
}


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; ReadOnlyLock : BaseLock
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; ReadOnlyLock(ReaderWriterLockSlim locks)
        : &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;base&lt;/span&gt;(locks)
    {
        Locks.GetReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;override&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose()
    {
        Locks.ReleaseReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }
}


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; WriteLock : BaseLock
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; WriteLock(ReaderWriterLockSlim locks)
        : &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;base&lt;/span&gt;(locks)
    {
        Locks.GetWriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;override&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose()
    {
        Locks.ReleaseWriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }
}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;span style="font-size:8pt;font-family:&amp;#39;Verdana&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;a href="http://devplanet.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/brianr.Code+Snippets/ThreadSafeDictionary.zip"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=12123" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/brianr/archive/tags/Threading/default.aspx">Threading</category><category domain="http://devplanet.com/blogs/brianr/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Thread Safe Dictionary in .NET with ReaderWriterLockSlim</title><link>http://devplanet.com/blogs/brianr/archive/2008/09/26/thread-safe-dictionary-in-net.aspx</link><pubDate>Fri, 26 Sep 2008 15:14:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:13</guid><dc:creator>Brian Rudolph</dc:creator><slash:comments>8</slash:comments><description>&lt;p&gt;Since&amp;nbsp;MS has decided to not include a thread-safe dictionary in the .NET framework, many of us have been forced to implement our own.&amp;nbsp; What MS has done&amp;nbsp;now with .NET 3.5 is given us a newer locking mechanism which makes this task easier.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Previously, we had 2 lock mechanisms, neither of which worked very well for my uses.&amp;nbsp; The first is the Lock statement.&amp;nbsp; While this method is effective, it causes serious contention issues with simultaneous reads\writes.&amp;nbsp; Since it is generally safe to execute multiple concurrent reads from a dictionary, this was a huge performance flaw as the Lock statement was forcing us to perform all actions against the object in a serial fashion.&lt;/p&gt;
&lt;p&gt;So that left ReaderWriterLock, which would allow us to take out Reader &amp;amp; Writer locks independently.&amp;nbsp; This seemed to be the answer.&amp;nbsp; Unfortunately, after further testing and review, MS and the dev communities warned against this lock type&amp;nbsp;as it could have unintended consequences in certain situations.&amp;nbsp; The explanations for these I will not go in to, a simple Google search will answer those questions.&amp;nbsp; For the most part, I don&amp;#39;t have the mental capacity to understand, much less explain the failures.&amp;nbsp; I will tell you that I have tested this method, and ran in to some issues, and subsequently abandoned the approach.&lt;/p&gt;
&lt;p&gt;With&amp;nbsp;.NET 3.5 comes the brand-spankin-new ReaderWriterLockSlim.&amp;nbsp;&amp;nbsp;ReaderWriterLockSlim is similar to the ReaderWriterLock in functionality, minus some of the drawbacks.&amp;nbsp; Of course any new approach will bring on its own consequences, and if you do a little research, you will find that Slim isn&amp;#39;t infallible either.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Many of our applications implement the Factory model.&amp;nbsp; Factory models are great, they are extensible, and they can be extremely performant.&amp;nbsp; With that said, any data driven application that uses the Factory model without a caching model, will most likely perform poorly.&amp;nbsp; So, in our factories, we build in a caching mechanism.&amp;nbsp; A very simple type and ID based cache that allows us to persist commonly used objects to in-memory cache for a specific amount of time.&amp;nbsp; I won&amp;#39;t go in to the implementation of this model here as every caching implementation has its own needs and wants.&lt;/p&gt;
&lt;p&gt;At the heart of this&amp;nbsp;and likely any caching model is inevitably a Dictionary or Dictionary like structure.&amp;nbsp; MS programmers have spent countless hours fine-tuning the Dictionary class to make it as performant as possible.&amp;nbsp; I challenge anyone to write a managed Dictionary that performs as well in such a wide variety of scenarios.&amp;nbsp; I&amp;#39;ve tried and failed.&amp;nbsp; Unfortunately, MS has not provided a thread-safe implementation.&amp;nbsp; Generally when you run into the question of thread-safety, most people have no idea what you are talking about.&amp;nbsp; The problem with writing truly thread-safe code that can work in any scenario is that you will sacrifice performance.&amp;nbsp; If you tailor your thread-safe mechanisms to your particular problem, you can generally maintain a higher level of performance.&lt;/p&gt;
&lt;p&gt;The reason we need thread-safety is not that we are specifically spawning threads.&amp;nbsp; In IIS, worker processes are inherently multi-threaded.&amp;nbsp; Therefore, using static objects in a web-farm generally requires some level of thread safety, otherwise you will get dreaded &amp;quot;An item with the same key has already been added&amp;quot; errors.&amp;nbsp; This is because between the time you check to see if a key already exists in your dictionary and the time you insert it, some other thread may have inserted this key.&amp;nbsp; This is especially the case in object factories, because you have multiple threads attempting to access/create objects and subsequently cache them.&lt;/p&gt;
&lt;p&gt;This is the code I&amp;#39;ve written.&amp;nbsp;&amp;nbsp;Update: This code has been tested, and is working well.&amp;nbsp; I will keep this post updated with any changes and test results.&amp;nbsp; I also have not made this class utilize lock escalation, which ReaderWriterLockSlim supports.&amp;nbsp; As always, &lt;strong&gt;please perform your own testing&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;table cellpadding="0" cellspacing="0" style="background-color:#f2f2f2;border:solid 1px #e5e5e5;width:100%;"&gt;
&lt;tr style="vertical-align:top;line-height:normal;"&gt;&lt;td&gt;&lt;pre style="overflow:scroll;margin:0px;padding:2px;padding-left:8px;"&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; System;
&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; System.Collections;
&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; System.Threading;


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;interface&lt;/span&gt; IThreadSafeDictionary&amp;lt;TKey, TValue&amp;gt; : IDictionary&amp;lt;TKey, TValue&amp;gt;
{
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Merge is similar to the SQL merge or upsert statement.  &lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;key&amp;quot;&amp;gt;Key to lookup&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;newValue&amp;quot;&amp;gt;New Value&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; MergeSafe(TKey key, TValue newValue);


    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is a blind remove. Prevents the need to check for existence first.&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;key&amp;quot;&amp;gt;Key to Remove&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; RemoveSafe(TKey key);
}


[Serializable]
&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; ThreadSafeDictionary&amp;lt;TKey, TValue&amp;gt; : IThreadSafeDictionary&amp;lt;TKey, TValue&amp;gt;
{
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//This is the internal dictionary that we are wrapping&lt;/span&gt;
    IDictionary&amp;lt;TKey, TValue&amp;gt; dict &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; Dictionary&amp;lt;TKey, TValue&amp;gt;();


    [NonSerialized]
    ReaderWriterLockSlim dictionaryLock &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; Locks.GetLockInstance(LockRecursionPolicy.NoRecursion); &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//setup the lock;&lt;/span&gt;


    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// This is a blind remove. Prevents the need to check for existence first.&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;key&amp;quot;&amp;gt;Key to remove&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; RemoveSafe(TKey key)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.ContainsKey(key))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
                {
                    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Remove(key);
                }
            }
        }
    }


    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// Merge does a blind remove, and then add.  Basically a blind Upsert.  &lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;key&amp;quot;&amp;gt;Key to lookup&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;/// &amp;lt;param name=&amp;quot;newValue&amp;quot;&amp;gt;New Value&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; MergeSafe(TKey key, TValue newValue)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock)) &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;// take a writelock immediately since we will always be writing&lt;/span&gt;
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.ContainsKey(key))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Remove(key);
            }


            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Add(key, newValue);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; Remove(TKey key)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Remove(key);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; ContainsKey(TKey key)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.ContainsKey(key);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; TryGetValue(TKey key, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;out&lt;/span&gt; TValue value)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.TryGetValue(key, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;out&lt;/span&gt; value);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; TValue &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;[TKey key]
    {
        get
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict[key];
            }
        }
        set
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict[key] &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; value;
            }
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;TKey&amp;gt; Keys
    {
        get
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; List&amp;lt;TKey&amp;gt;(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Keys);
            }
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;TValue&amp;gt; Values
    {
        get
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; List&amp;lt;TValue&amp;gt;(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Values);
            }
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Clear()
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Clear();
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; Count
    {
        get
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Count;
            }
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; Contains(KeyValuePair&amp;lt;TKey, TValue&amp;gt; item)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Contains(item);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Add(KeyValuePair&amp;lt;TKey, TValue&amp;gt; item)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Add(item);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Add(TKey key, TValue value)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Add(key, value);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; Remove(KeyValuePair&amp;lt;TKey, TValue&amp;gt; item)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; WriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.Remove(item);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; CopyTo(KeyValuePair&amp;lt;TKey, TValue&amp;gt;[] array, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; arrayIndex)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.CopyTo(array, arrayIndex);
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; IsReadOnly
    {
        get
        {
            &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dictionaryLock))
            {
                &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;.dict.IsReadOnly;
            }
        }
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;virtual&lt;/span&gt; IEnumerator&amp;lt;KeyValuePair&amp;lt;TKey, TValue&amp;gt;&amp;gt; GetEnumerator()
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;throw&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; NotSupportedException(&lt;span style="color:#666666;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&amp;quot;Cannot enumerate a threadsafe dictionary.  Instead, enumerate the keys or values collection&amp;quot;&lt;/span&gt;);
    }


    IEnumerator IEnumerable.GetEnumerator()
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;throw&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; NotSupportedException(&lt;span style="color:#666666;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&amp;quot;Cannot enumerate a threadsafe dictionary.  Instead, enumerate the keys or values collection&amp;quot;&lt;/span&gt;);
    }
}


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; Locks
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; GetReadLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (!lockAcquired)
            lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; locks.TryEnterUpgradeableReadLock(1);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; GetReadOnlyLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (!lockAcquired)
            lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; locks.TryEnterReadLock(1);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; GetWriteLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;bool&lt;/span&gt; lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;false&lt;/span&gt;;
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (!lockAcquired)
            lockAcquired &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; locks.TryEnterWriteLock(1);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; ReleaseReadOnlyLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (locks.IsReadLockHeld)
            locks.ExitReadLock();
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; ReleaseReadLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (locks.IsUpgradeableReadLockHeld)
            locks.ExitUpgradeableReadLock();
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; ReleaseWriteLock(ReaderWriterLockSlim locks)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (locks.IsWriteLockHeld)
            locks.ExitWriteLock();
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; ReleaseLock(ReaderWriterLockSlim locks)
    {
        ReleaseWriteLock(locks);
        ReleaseReadLock(locks);
        ReleaseReadOnlyLock(locks);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; ReaderWriterLockSlim GetLockInstance()
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; GetLockInstance(LockRecursionPolicy.SupportsRecursion);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; ReaderWriterLockSlim GetLockInstance(LockRecursionPolicy recursionPolicy)
    {
        &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; ReaderWriterLockSlim(recursionPolicy);
    }
}


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; BaseLock : IDisposable
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;protected&lt;/span&gt; ReaderWriterLockSlim _Locks;


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; BaseLock(ReaderWriterLockSlim locks)
    {
        _Locks &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; locks;
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose();
}


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; ReadLock : BaseLock
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; ReadLock(ReaderWriterLockSlim locks)
        : &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;base&lt;/span&gt;(locks)
    {
        Locks.GetReadLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;override&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose()
    {
        Locks.ReleaseReadLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }
}


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; ReadOnlyLock : BaseLock
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; ReadOnlyLock(ReaderWriterLockSlim locks)
        : &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;base&lt;/span&gt;(locks)
    {
        Locks.GetReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;override&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose()
    {
        Locks.ReleaseReadOnlyLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }
}


&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; WriteLock : BaseLock
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; WriteLock(ReaderWriterLockSlim locks)
        : &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;base&lt;/span&gt;(locks)
    {
        Locks.GetWriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }


    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;override&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Dispose()
    {
        Locks.ReleaseWriteLock(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;this&lt;/span&gt;._Locks);
    }
}


 &lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;[Update]&lt;br /&gt;Through some testing, I found the need to update the ThreadSafe Dictionary.&amp;nbsp; I changed all of the locking to use IDisposables to ensure lock creation and destruction.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=13" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/brianr/archive/tags/Dictionary/default.aspx">Dictionary</category><category domain="http://devplanet.com/blogs/brianr/archive/tags/Threading/default.aspx">Threading</category><category domain="http://devplanet.com/blogs/brianr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://devplanet.com/blogs/brianr/archive/tags/IDisposable/default.aspx">IDisposable</category></item><item><title>I'm an MVP!</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2008/07/02/i-m-an-mvp.aspx</link><pubDate>Wed, 02 Jul 2008 06:26:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:3577</guid><dc:creator>Chuck</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I found out this morning that I&amp;#39;ve been named a SQL Server MVP (Most Valuable Professional).&lt;/p&gt;
&lt;p&gt;For those of you who don&amp;#39;t know what the MVP program is, here&amp;#39;s a brief overview.&lt;/p&gt;
&lt;p&gt;Each quarter, Microsoft selects a group of people across many different technologies to become MVPs.&amp;nbsp; Your selection is based on your community involvement over the past year.&amp;nbsp; Community involvement can include presenting at user group meetings, posting answers to questions on newsgroups, writing articles for online magazines, etc.&lt;/p&gt;
&lt;p&gt;My community involvement is primarily through the Professional Association for SQL Server (&lt;a class="" href="http://www.sqlpass.org/" target="_blank"&gt;PASS&lt;/a&gt;).&amp;nbsp; I currently serve on the Board of Directors and am in charge of two techincal publications - a newsletter that goes out every other week and a magazine that goes out every other month.&lt;/p&gt;
&lt;p&gt;Thank you to everyone who has supported my efforts in the community over the years.&amp;nbsp; You&amp;#39;ll probably be seeing much more of me out there in the future.&lt;/p&gt;
&lt;p&gt;Chuck&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=3577" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/PASS/default.aspx">PASS</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/MVP/default.aspx">MVP</category></item><item><title>SQL Server 2008 RC0</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2008/06/13/sql-server-2008-rc0.aspx</link><pubDate>Fri, 13 Jun 2008 18:39:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:2775</guid><dc:creator>Chuck</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;For those of you who haven&amp;#39;t heard, RC0 of SQL Server 2008 has been released.&lt;/p&gt;
&lt;p&gt;If you have played with any of the CTP releases of SQL Server 2008, you&amp;#39;ll notice that there are a few differences in the installer - but not enough to cause you to relearn anything.&lt;/p&gt;
&lt;p&gt;I loaded it up on my dev box this week, and I am quite impressed with what I am seeing so far.&amp;nbsp; There&amp;#39;s a nice new Activity Monitor that is similar to the default view of the Vista Reliability and Performance Monitor - and it even works against SQL Server 2005 servers.&lt;/p&gt;
&lt;p&gt;Over the next couple of months, I&amp;#39;ll be writing some fairly detailed blog posts on SQL Server 2008 - each of them based on a different new feature.&amp;nbsp; Keep checking back - I hope to profile at least one new feature every other week.&lt;/p&gt;
&lt;p&gt;Chuck&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=2775" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/SQL+Server+2008/default.aspx">SQL Server 2008</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Features/default.aspx">Features</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/CTP/default.aspx">CTP</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/RC0/default.aspx">RC0</category></item><item><title>TechEd Developer - Day 3</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2008/06/06/teched-developer-day-3.aspx</link><pubDate>Fri, 06 Jun 2008 20:14:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:2509</guid><dc:creator>Chuck</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Another day, more booth duty.&amp;nbsp; I spent a good part of my day working with the VSTS Database Edition team.&amp;nbsp; Great group of people - and they have a great product.&amp;nbsp; It is nice talking to people who have no idea how the product can help them.&amp;nbsp; When they see what it can do, they normally want to get it in place quick.&lt;/p&gt;
&lt;p&gt;I also caught a session on a new in-memory distributed&amp;nbsp;caching technology from Microsoft codenamed &amp;quot;Velocity&amp;quot;.&amp;nbsp; It is quite impressive.&amp;nbsp; It can actually be an in-memory store for your IIS Session State - and it allows you to move from machine to machine in a web farm without losing your session!&lt;/p&gt;
&lt;p&gt;More to come on Day 4!&lt;/p&gt;
&lt;p&gt;Chuck&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=2509" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Data+Dude/default.aspx">Data Dude</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/TechEd/default.aspx">TechEd</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Velocity/default.aspx">Velocity</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/VSTS+Database+Edition/default.aspx">VSTS Database Edition</category></item><item><title>TechEd Developer - Day 2</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2008/06/05/teched-developer-day-2.aspx</link><pubDate>Thu, 05 Jun 2008 20:35:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:2483</guid><dc:creator>Chuck</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I spent a bunch of time today in the SQL Server TLC area down on the show floor.&amp;nbsp; I did, however, manage to get away for a great session on Extended Events presented by Bob Beauchemin - who I had dinner with the night before at a great Brazilian steakhouse.&amp;nbsp; It&amp;#39;s amazing all that you can do with the extended events architecture.&lt;/p&gt;
&lt;p&gt;More to come tomorrow.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=2483" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/TechEd/default.aspx">TechEd</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Extended+Events/default.aspx">Extended Events</category></item><item><title>TechEd Developer - Day 1</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2008/06/03/teched-developer-day-1.aspx</link><pubDate>Tue, 03 Jun 2008 15:10:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:2375</guid><dc:creator>Chuck</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I just got out of the keynote for TechEd Developer.&amp;nbsp; Bill Gates actually opened up for a Q&amp;amp;A session from the floor.&amp;nbsp; Quite impressive.&lt;/p&gt;
&lt;p&gt;It was announced that Silverlight 2 Beta 2 will be released by the end of the week, and that you will be able to get a Go-Live license.&amp;nbsp; I know some of my co-workers will be happy about that.&lt;/p&gt;
&lt;p&gt;I&amp;#39;m getting ready to go do my first shift in the TLC area.&amp;nbsp; I&amp;#39;ll be working the SQL Server area (look for the green).&amp;nbsp; Today I&amp;#39;ll be at the Storage demo station.&amp;nbsp; The rest of the week I&amp;#39;ll be splitting my time between Storage and Team Edition for Database Professionals.&amp;nbsp; If you&amp;#39;re here, stop by and say hi!&lt;/p&gt;
&lt;p&gt;That&amp;#39;s all for now.&amp;nbsp; I&amp;#39;ll have more to report later.&lt;/p&gt;
&lt;p&gt;Chuck&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=2375" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/TechEd/default.aspx">TechEd</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Keynote/default.aspx">Keynote</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/SilverLight/default.aspx">SilverLight</category></item><item><title>TechEd Developer</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2008/05/30/teched-developer.aspx</link><pubDate>Fri, 30 May 2008 21:15:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:2279</guid><dc:creator>Chuck</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;If you&amp;#39;re going to be at TechEd in Orlando next week, stop by and say Hi!&amp;nbsp; I&amp;#39;ll be in the Microsoft TLC area over lunch Tuesday through Friday.&amp;nbsp; I&amp;#39;ll be helping out the VSTS folks.&amp;nbsp; Hope to see you there.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=2279" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Data+Dude/default.aspx">Data Dude</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/TechEd/default.aspx">TechEd</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Conferences/default.aspx">Conferences</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>PASS Call for Presentations - Deadline Extended Again!</title><link>http://devplanet.com/blogs/memydatabaseandi/archive/2008/04/01/pass-call-for-presentations-deadline-extended-again.aspx</link><pubDate>Tue, 01 Apr 2008 16:39:00 GMT</pubDate><guid isPermaLink="false">6e120f4b-f509-4111-8fd8-03bc0d0a75d9:632</guid><dc:creator>Chuck</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Due to technical difficulties, the deadline for submitting abstracts for the 2008 PASS Community Summit has been extended through Monday, April 7, 2008.&lt;/p&gt;
&lt;p&gt;If you are interested in submitting an abstract, please do so at &lt;a href="http://calltospeakers.sqlpass.org/"&gt;http://calltospeakers.sqlpass.org/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Chuck&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devplanet.com/aggbug.aspx?PostID=632" width="1" height="1"&gt;</description><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/PASS/default.aspx">PASS</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/PASS+Community+Summit/default.aspx">PASS Community Summit</category><category domain="http://devplanet.com/blogs/memydatabaseandi/archive/tags/Call+for+Presentations/default.aspx">Call for Presentations</category></item></channel></rss>
