<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C#</title><link>http://www.styledesign.biz/weblogs/macinnesm/category/11.aspx</link><description>C#</description><managingEditor>Marcus Mac Innes</managingEditor><dc:language>en-IE</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>Marcus Mac Innes</dc:creator><title>WARNING: Serious ASP.NET issue with Windows Server 2003 and SP1</title><link>http://www.styledesign.biz/weblogs/macinnesm/archive/2005/08/04/993.aspx</link><pubDate>Thu, 04 Aug 2005 17:20:00 GMT</pubDate><guid>http://www.styledesign.biz/weblogs/macinnesm/archive/2005/08/04/993.aspx</guid><wfw:comment>http://www.styledesign.biz/weblogs/macinnesm/comments/993.aspx</wfw:comment><comments>http://www.styledesign.biz/weblogs/macinnesm/archive/2005/08/04/993.aspx#Feedback</comments><slash:comments>59</slash:comments><wfw:commentRss>http://www.styledesign.biz/weblogs/macinnesm/comments/commentRss/993.aspx</wfw:commentRss><trackback:ping>http://www.styledesign.biz/weblogs/macinnesm/services/trackbacks/993.aspx</trackback:ping><description>&lt;P&gt;We have been trying to track down a problem with our blog aggregator software &lt;A href="http://www.styledesign.biz/weblogs/macinnesm/archive/2004/11/29/273.aspx"&gt;B.AG&lt;/A&gt; which is currently powering &lt;A href="http://www.developers.ie"&gt;INDA&lt;/A&gt;'s blog aggregator at &lt;A href="http://www.developers.ie/blogs"&gt;www.developers.ie/blogs&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;We recently upgraded the server to Windows Server 2003 SP1 and for some reason, threads were simply disappearing from our custom threadpool and the application logging which uses &lt;A href="http://logging.apache.org/log4net/"&gt;log4net&lt;/A&gt; would simply stop without warning. We have just tracked the problem down to the System.Threading.Timer class which according to &lt;A href="http://arje.net/halcyon_days_of_system.threading.timer"&gt;this&lt;/A&gt; has major issues when running on &lt;A href="http://www.microsoft.com/windowsserver2003/default.mspx"&gt;Windows Server 2003&lt;/A&gt; with &lt;A href="http://www.microsoft.com/windowsserver2003/downloads/servicepacks/sp1/default.mspx"&gt;SP1&lt;/A&gt;. It seems the Timer class stops firing at some random&amp;nbsp;point and never fires again...&lt;/P&gt;
&lt;P&gt;I know of a number of major ASP.NET sites around the world that have applications that depend on functionality provided by the Timer class and I'm very surprised that this issue has not seen more publicity. So this is just a warning to ensure that you don't fall victim to this issue!&lt;/P&gt;
&lt;P&gt;As far am I am aware there is no hotfix available&amp;nbsp;for this problem yet.&lt;/P&gt;&lt;img src ="http://www.styledesign.biz/weblogs/macinnesm/aggbug/993.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Marcus Mac Innes</dc:creator><title>WS-ReliableMessaging for WSE 2.0</title><link>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/11/30/278.aspx</link><pubDate>Tue, 30 Nov 2004 17:31:00 GMT</pubDate><guid>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/11/30/278.aspx</guid><wfw:comment>http://www.styledesign.biz/weblogs/macinnesm/comments/278.aspx</wfw:comment><comments>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/11/30/278.aspx#Feedback</comments><slash:comments>34</slash:comments><wfw:commentRss>http://www.styledesign.biz/weblogs/macinnesm/comments/commentRss/278.aspx</wfw:commentRss><trackback:ping>http://www.styledesign.biz/weblogs/macinnesm/services/trackbacks/278.aspx</trackback:ping><description>&lt;P&gt;&lt;A href="http://weblogs.asp.net/andresv/"&gt;Andres&lt;/A&gt; has released the code for an implementation of &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnglobspec/html/wsrmspecindex.asp"&gt;WS-ReliableMessaging&lt;/A&gt; via his blog &lt;A href="http://weblogs.asp.net/andresv/archive/2004/11/28/271255.aspx"&gt;here&lt;/A&gt;. I've taken a quick look at the code and it looks good.&lt;/P&gt;
&lt;P&gt;There was quite a bit of talk a few months back about how WS-ReliableMessaging&amp;nbsp;should be implemented. The discussion mainly revolved around where the RM Sequence should be created and terminated in the implementation so as fit nicely with the different &lt;A href="http://msdn.microsoft.com/webservices/building/wse/default.aspx"&gt;WSE 2.0&lt;/A&gt;&amp;nbsp;channels. This implementation preserves &lt;A href="http://msdn.microsoft.com/webservices/building/wse/default.aspx"&gt;WSE 2.0&lt;/A&gt; by simply sub classing SoapSender and SoapReceiver and providing a SequenceManager.&lt;/P&gt;
&lt;P&gt;Regarding message correlation, &lt;A href="http://weblogs.asp.net/andresv/"&gt;Andres&lt;/A&gt;'s implements a MemoryStorageProvider only, but looking at the code, it would be relatively easy to build the DBStorageProvider which implements IMessageStorageProvider.&lt;/P&gt;
&lt;P&gt;Some other nice features include integration with a WSCompression library and a ton of useful Utility classes suitable as good examples for those who are starting out...&lt;/P&gt;
&lt;P&gt;&lt;A href="http://weblogs.asp.net/cweyer/"&gt;Christian Weyer&lt;/A&gt; of &lt;A href="http://sourceforge.net/projects/plumbworkorange/"&gt;Plumbwork Orange&lt;/A&gt; fame has also indicated that the code might be integrated into the &lt;A href="http://sourceforge.net/projects/plumbworkorange/"&gt;Plumbwork Orange&lt;/A&gt;&amp;nbsp;mainline. This would be very&amp;nbsp;interesting and would definitely give &lt;A href="http://www.dynamic-cast.com/"&gt;Hervey Wilson&lt;/A&gt;&amp;nbsp;something to think about (and measure against)&amp;nbsp;for the WSE 3.0 feature list...&lt;/P&gt;
&lt;P&gt;Well done to Andres on getting this first implementation (that I have heard of) out there!&lt;/P&gt;&lt;img src ="http://www.styledesign.biz/weblogs/macinnesm/aggbug/278.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Marcus Mac Innes</dc:creator><title>TestDriven.NET 1.0 Released</title><link>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/11/30/276.aspx</link><pubDate>Tue, 30 Nov 2004 12:42:00 GMT</pubDate><guid>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/11/30/276.aspx</guid><wfw:comment>http://www.styledesign.biz/weblogs/macinnesm/comments/276.aspx</wfw:comment><comments>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/11/30/276.aspx#Feedback</comments><slash:comments>168</slash:comments><wfw:commentRss>http://www.styledesign.biz/weblogs/macinnesm/comments/commentRss/276.aspx</wfw:commentRss><trackback:ping>http://www.styledesign.biz/weblogs/macinnesm/services/trackbacks/276.aspx</trackback:ping><description>&lt;P&gt;&lt;A href="http://www.testdriven.net/"&gt;TestDriven.NET,&lt;/A&gt; a handy addin for Visual Studio which allows you to run unit tests from pretty much anywhere from&amp;nbsp;within VS.NET was released as version 1.0 yesterday...&lt;/P&gt;&lt;img src ="http://www.styledesign.biz/weblogs/macinnesm/aggbug/276.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Marcus Mac Innes</dc:creator><title>When is a Unit Test not really a Unit Test</title><link>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/11/05/214.aspx</link><pubDate>Fri, 05 Nov 2004 09:46:00 GMT</pubDate><guid>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/11/05/214.aspx</guid><wfw:comment>http://www.styledesign.biz/weblogs/macinnesm/comments/214.aspx</wfw:comment><comments>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/11/05/214.aspx#Feedback</comments><slash:comments>55</slash:comments><wfw:commentRss>http://www.styledesign.biz/weblogs/macinnesm/comments/commentRss/214.aspx</wfw:commentRss><trackback:ping>http://www.styledesign.biz/weblogs/macinnesm/services/trackbacks/214.aspx</trackback:ping><description>&lt;P&gt;&lt;A href="http://udidahan.weblogs.us/"&gt;Udi Dahan&lt;/A&gt; has posted an interesting article for anyone thinking about writing unit tests when implementing Test Driven Development (TDD) &lt;A href="http://udidahan.weblogs.us/archives/021381.html"&gt;here&lt;/A&gt;. In the article he explains how the use of mock objects allows test writers to de-couple the implementation of the test code from dependent objects and thus enabling you to have a true "Unit Test".&lt;/P&gt;
&lt;P&gt;For more information on mock objects and Udi's use of&amp;nbsp;:&lt;!--StartFragment --&gt;&lt;/P&gt;&lt;PRE&gt;Mock mock &lt;SPAN class=syntax11&gt;=&lt;/SPAN&gt; &lt;SPAN class=syntax6&gt;&lt;FONT color=#0000ff&gt;new&lt;/FONT&gt;&lt;/SPAN&gt; &lt;SPAN class=syntax9&gt;DynamicMock&lt;/SPAN&gt;(&lt;SPAN class=syntax6&gt;&lt;FONT color=#0000ff&gt;typeof&lt;/FONT&gt;&lt;/SPAN&gt;(Something))&lt;SPAN class=syntax11&gt;;&lt;/SPAN&gt; &lt;FONT color=#008000&gt;&lt;SPAN class=syntax1&gt;//&lt;/SPAN&gt; &lt;SPAN class=syntax1&gt;create&lt;/SPAN&gt; &lt;SPAN class=syntax1&gt;a&lt;/SPAN&gt; &lt;SPAN class=syntax1&gt;mock&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;check out &lt;A href="http://nmock.truemesh.com/index.html"&gt;NMock&lt;/A&gt;, a mock object framework for .NET.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src ="http://www.styledesign.biz/weblogs/macinnesm/aggbug/214.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Marcus Mac Innes</dc:creator><title>.NET 2.0 Beta 2 May Be Around The Corner...</title><link>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/10/23/206.aspx</link><pubDate>Sat, 23 Oct 2004 23:43:00 GMT</pubDate><guid>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/10/23/206.aspx</guid><wfw:comment>http://www.styledesign.biz/weblogs/macinnesm/comments/206.aspx</wfw:comment><comments>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/10/23/206.aspx#Feedback</comments><slash:comments>229</slash:comments><wfw:commentRss>http://www.styledesign.biz/weblogs/macinnesm/comments/commentRss/206.aspx</wfw:commentRss><trackback:ping>http://www.styledesign.biz/weblogs/macinnesm/services/trackbacks/206.aspx</trackback:ping><description>&lt;P&gt;&lt;A href="http://weblogs.asp.net/scottgu"&gt;Scott Guthrie&lt;/A&gt; has &lt;A href="http://weblogs.asp.net/scottgu/archive/2004/10/23/246707.aspx"&gt;returned to blogging&lt;/A&gt; with &lt;A href="http://weblogs.asp.net/scottgu/archive/2004/10/23/246709.aspx"&gt;this insightful blog&lt;/A&gt; about some of the internal project management and testing&amp;nbsp;techniques currently being adopted by the ASP.NET team for the next release of Microsoft ASP.NET 2.0, Beta 2.&lt;/P&gt;
&lt;P&gt;Interestingly, Scott mentions that the Beta 2 milestone is now only 3 weeks away... Positive news after this week's &lt;A href="http://www.theserverside.net/news/thread.tss?thread_id=29537"&gt;announcement of yet another delay&lt;/A&gt; to the final release of VS.NET 2.0 and SQL Server 2005.&lt;/P&gt;
&lt;P&gt;Maybe it's the SQL Server team delaying things this time in an attempt to put back the &lt;A href="http://www.styledesign.biz/weblogs/macinnesm/archive/2004/09/22/197.aspx"&gt;diagram&lt;/A&gt;!&lt;/P&gt;&lt;img src ="http://www.styledesign.biz/weblogs/macinnesm/aggbug/206.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Marcus Mac Innes</dc:creator><title>How to Configure WSE 2.0 Services Behind a NAT Router.</title><link>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/09/26/203.aspx</link><pubDate>Sun, 26 Sep 2004 16:32:00 GMT</pubDate><guid>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/09/26/203.aspx</guid><wfw:comment>http://www.styledesign.biz/weblogs/macinnesm/comments/203.aspx</wfw:comment><comments>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/09/26/203.aspx#Feedback</comments><slash:comments>98</slash:comments><wfw:commentRss>http://www.styledesign.biz/weblogs/macinnesm/comments/commentRss/203.aspx</wfw:commentRss><trackback:ping>http://www.styledesign.biz/weblogs/macinnesm/services/trackbacks/203.aspx</trackback:ping><description>&lt;P&gt;When I recently put a bunch of Microsoft Web Service Enhancements (WSE 2.0) services to the test across an Internet based connection I&amp;nbsp;was in for a surprise&amp;#8230;&lt;/P&gt;
&lt;P&gt;I hadn&amp;#8217;t counted on the problem of trying to configure WSE to work behind our &amp;#8220;Gateway to the Internet&amp;#8221;, the Network Address Translation (NAT) router!&lt;/P&gt;
&lt;P&gt;Our office LAN sits behind a router/firewall which &amp;#8216;protects&amp;#8217; it from the 2Mbit broadband Internet pipe. All but the necessary TCP/IP ports are blocked and all workstation machines are running Windows XP Service Pack 2 with the firewall enabled.&lt;/P&gt;
&lt;P&gt;The preliminaries to getting it all running include the usual:&lt;/P&gt;
&lt;P&gt;1)&amp;nbsp;Opening up the relevant TCP/IP port on the firewall. (The default port for the soap.tcp transport is 8081)&lt;/P&gt;
&lt;P&gt;2)&amp;nbsp;NAT mapping of the router port 8081 to the test server or workstation&amp;#8217;s port 8081.&lt;/P&gt;
&lt;P&gt;3)&amp;nbsp;If using Windows XP SP2 as a test machine, then add the service host application to the list program exceptions for incoming network connections in Windows Firewall.&lt;/P&gt;
&lt;P&gt;And this is where it gets a little tricky&amp;#8230;&lt;/P&gt;
&lt;P&gt;A problem arises from the fact that the external IP address belongs to the router and not the machine which is hosting the service. This machine hosting the service has its own internal IP address which is not visible from the outside.&lt;/P&gt;
&lt;P&gt;But WSE doesn&amp;#8217;t allow binding a SoapService to an IP address that is not local to the machine. i.e. you cannot bind to the router&amp;#8217;s IP address, you can only bind to a address such as localhost. &lt;/P&gt;
&lt;P&gt;If you try, you get the following error: WSE813: The following transport address could not be mapped to a local network interface: soap.tcp://&amp;lt;RouterIPAddress&amp;gt;.&lt;/P&gt;
&lt;P&gt;Furthermore if you bind your SoapService to localhost then all incoming network connections that originate from the local network are received by WSE and are served correctly. Incoming connections that originate from outside the firewall however are addressed to the router. Since the router (using NAT) is configured to map these incoming connections to the internal machine which is hosting the service, the message is indeed routed to the correct host application&amp;#8230;&lt;/P&gt;
&lt;P&gt;But upon receiving these external messages WSE rejects the request and reports &amp;#8220;Destination Unreachable&amp;#8221; back to the client. The reason for this is simple, WSE uses WS-Addressing and the wsa:To address is not referencing this machine, its referencing an endpoint on the router.&lt;/P&gt;
&lt;P&gt;After some investigation, trial and error and finally common sense, the answer was quite simple, employ the use of WS-Addressing&amp;#8217;s wsa:Via&amp;nbsp; as follows. &lt;/P&gt;
&lt;P&gt;Register the SoapService using a logical name such as &amp;#8220;MyService&amp;#8221; and a Via: specifying the IP address of the machine hosting the service:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;MyService service = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; MyService();&lt;BR&gt;Uri logical = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; Uri("urn:MyService"); &lt;BR&gt;Uri via = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; Uri("soap.tcp://&amp;lt;ServiceHostIPAddress&amp;gt;");&lt;BR&gt;EndpointReference epr = new EndpointReference(logical, via);&lt;BR&gt;SoapReceivers.Add(epr, service);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;On the client you do something similar except specify the router&amp;#8217;s IP address:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff&gt;public class&lt;/FONT&gt; MyClient : SoapClient {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;public&lt;/FONT&gt; MyClient() : &lt;FONT color=#0000ff&gt;base&lt;/FONT&gt;(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; EndpointReference(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; Uri("urn:MyService"),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; Uri("soap.tcp://&amp;lt;RouterIPAddress&amp;gt;")) {}&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Easy as that!&lt;/P&gt;&lt;img src ="http://www.styledesign.biz/weblogs/macinnesm/aggbug/203.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Marcus Mac Innes</dc:creator><title>Synchronized .NET Collection Classes are NOT Thread Safe.</title><link>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/09/21/196.aspx</link><pubDate>Tue, 21 Sep 2004 12:01:00 GMT</pubDate><guid>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/09/21/196.aspx</guid><wfw:comment>http://www.styledesign.biz/weblogs/macinnesm/comments/196.aspx</wfw:comment><comments>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/09/21/196.aspx#Feedback</comments><slash:comments>328</slash:comments><wfw:commentRss>http://www.styledesign.biz/weblogs/macinnesm/comments/commentRss/196.aspx</wfw:commentRss><trackback:ping>http://www.styledesign.biz/weblogs/macinnesm/services/trackbacks/196.aspx</trackback:ping><description>&lt;P&gt;Call me a purist, but when someone asks me whether something is thread safe, I like to re-phrase the question in my head to something like "Is this air traffic control system thread safe" before answering...Yes or No?&lt;/P&gt;
&lt;P&gt;So you can imagine my surprise then after finally tracking down a threading issue only to discover that the bug was in fact caused by the .NET synchronized &lt;FONT face="Courier New"&gt;Hashtable&lt;/FONT&gt; and it turns out that the synchronized &lt;FONT face="Courier New"&gt;Hashtable&lt;/FONT&gt; is in fact not thread safe, but thread safe "ish" and to me that's NOT thread safe at all.&lt;/P&gt;
&lt;P&gt;The documentation for Hashtable and other collection objects which implement &lt;FONT face="Courier New"&gt;System.Collections.ICollection&lt;/FONT&gt; indicates that the static method &lt;FONT face="Courier New"&gt;Synchronized&lt;/FONT&gt; "Returns a synchronized (thread-safe) wrapper for the Hashtable.". Creating one coundn't be simpler, a small change in the Hashtable's initialisation provides you with thread safety...&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;Hashtable threadSafeHashtable = Hashtable.Synchronized(&lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; Hashtable());&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;The &lt;FONT face="Courier New"&gt;Hashtable&lt;/FONT&gt; class contains a private class called &lt;FONT face="Courier New"&gt;SyncHashtable&lt;/FONT&gt; which&amp;nbsp;simply subclasses &lt;FONT face="Courier New"&gt;Hashtable&lt;/FONT&gt; and overrides its&amp;nbsp;properties and methods. In reality, these wrappers synchronize data access by simply wrapping access in a&amp;nbsp;&lt;FONT face="Courier New" color=#0000ff&gt;lock&lt;/FONT&gt; statement. Here is the &lt;FONT face="Courier New"&gt;Hashtable&lt;/FONT&gt;'s synchronized &lt;FONT face="Courier New"&gt;Add&lt;/FONT&gt; method:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff&gt;public override void&lt;/FONT&gt; Add(&lt;FONT color=#0000ff&gt;object&lt;/FONT&gt; key, &lt;FONT color=#0000ff&gt;object&lt;/FONT&gt; value)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;lock&lt;/FONT&gt; (&lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;._table.SyncRoot)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;._table.Add(key, value);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Perfect right?&lt;/P&gt;
&lt;P&gt;Well not exactly... You see the Add method above is thread safe. Only one thread can add to the &lt;FONT face="Courier New"&gt;Hashtable&lt;/FONT&gt; at a time. But if we look a little closer, we find that not all properties and methods provide lock safety. Here is the implementation of the indexer which you will notice is missing a lock on the "get":&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff&gt;public override&lt;/FONT&gt; object &lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;[&lt;FONT color=#0000ff&gt;object&lt;/FONT&gt; key]&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;get&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;._table[key];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;set&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;lock&lt;/FONT&gt; (&lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;._table.SyncRoot)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;._table[key] = &lt;FONT color=#0000ff&gt;value&lt;/FONT&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This is a typical example of naive thread safety. The assumption goes that mutliple threads can simultaneously read from an object safely, but only one thread at a time can write to the object safely. And this is the implementation we see in &lt;FONT face="Courier New"&gt;System.Collection.Hashtable&lt;/FONT&gt; (above).&lt;/P&gt;
&lt;P&gt;This design works perfectly well and provides optimum performance since we are not holding up threads who only wish to read an objects data, they simply work away oblivious to each other, only when a thread wishes to write does it need to synchronize its access to the data. There is however one HUGE assumption in this design, the writes must be "atomic".&lt;/P&gt;
&lt;P&gt;In some cases writes to memory locations are actually atomic. For instance setting a value of a &lt;FONT face="Courier New" color=#0000ff&gt;bool&lt;/FONT&gt;&amp;nbsp;or&amp;nbsp;&lt;FONT face="Courier New" color=#0000ff&gt;int&lt;/FONT&gt; on 32bit single processor machine&amp;nbsp;in .NET 1.1 just happens to be atomic. We run into problems on multi processor machines however due to processor level memory caching and often need to qualify writes with &lt;FONT face="Courier New"&gt;System.Threading.Thread.MemoryBarrier()&lt;/FONT&gt; (discussed &lt;A href="http://blogs.msdn.com/brada/archive/2004/05/12/130935.aspx"&gt;here&lt;/A&gt;) which flushes the processor's memory cache. But now we have 2 separate&amp;nbsp;statements which together are definitely not atomic.&lt;/P&gt;
&lt;P&gt;So why is this important when looking at the synchronization design of the &lt;FONT face="Courier New"&gt;System.Collections.Hashtable.SyncHashtable&lt;/FONT&gt; class?&lt;/P&gt;
&lt;P&gt;Well if a thread always has the green light to perform a read, then it makes the assumption that the data to be read exists in a fully written state. If it were allowed to read "while" another thread was in the middle of write (albeit one thread writing at a time), then the data could be half written when the read is performed and hence we have a subtle and often difficult to locate threading bug.&lt;/P&gt;
&lt;P&gt;Other methods on &lt;FONT face="Courier New"&gt;SyncHashtable&lt;/FONT&gt; that fall foul of the design flaw include: &lt;FONT face="Courier New"&gt;Contains&lt;/FONT&gt;, &lt;FONT face="Courier New"&gt;ContainsKey&lt;/FONT&gt;, &lt;FONT face="Courier New"&gt;ContainsValue&lt;/FONT&gt;, &lt;FONT face="Courier New"&gt;CopyTo&lt;/FONT&gt;, &lt;FONT face="Courier New"&gt;GetEnumerator&lt;/FONT&gt;, &lt;FONT face="Courier New"&gt;GetHash&lt;/FONT&gt; and &lt;FONT face="Courier New"&gt;KeyEquals&lt;/FONT&gt;.&lt;/P&gt;
&lt;P&gt;Don't get caught out!&lt;/P&gt;
&lt;P&gt;[Update:]&amp;nbsp;As of .NET v2.0.40607 &lt;FONT face="Courier New"&gt;SyncHashtable.CopyTo&lt;/FONT&gt; has been upgraded to include a &lt;FONT face="Courier New" color=#0000ff&gt;lock&lt;/FONT&gt;.&lt;/P&gt;&lt;img src ="http://www.styledesign.biz/weblogs/macinnesm/aggbug/196.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Marcus Mac Innes</dc:creator><title>HOTFIX 831419 makes the list for .NET 1.1 SP1</title><link>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/09/01/192.aspx</link><pubDate>Wed, 01 Sep 2004 11:22:00 GMT</pubDate><guid>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/09/01/192.aspx</guid><wfw:comment>http://www.styledesign.biz/weblogs/macinnesm/comments/192.aspx</wfw:comment><comments>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/09/01/192.aspx#Feedback</comments><slash:comments>123</slash:comments><wfw:commentRss>http://www.styledesign.biz/weblogs/macinnesm/comments/commentRss/192.aspx</wfw:commentRss><trackback:ping>http://www.styledesign.biz/weblogs/macinnesm/services/trackbacks/192.aspx</trackback:ping><description>&lt;P&gt;&lt;A href="http://blogs.msdn.com/ericgu/"&gt;Eric Gunnerson&lt;/A&gt;&amp;nbsp;blogs about the recent release of .NET 1.1 SP1 &lt;A href="http://blogs.msdn.com/ericgu/archive/2004/08/30/222978.aspx"&gt;here&lt;/A&gt;. For those of you that were hoping for the inclusion of &lt;A href="http://support.microsoft.com/?kbid=831419"&gt;HOTFIX 831419&lt;/A&gt;&amp;nbsp;which is not listed in the list of official &lt;A href="http://support.microsoft.com/?kbid=867460"&gt;bug fixes&lt;/A&gt;, don't dispair... It's in there!&lt;/P&gt;
&lt;P&gt;[edit] &lt;A href="http://www.shahine.com/omar/default.aspx"&gt;Omar&lt;/A&gt;&amp;nbsp;gives a short code example &lt;A href="http://www.shahine.com/omar/PermaLink,guid,dcb28d18-5284-434a-a641-cd9917b72be2.aspx"&gt;here&lt;/A&gt; for using the fix.&lt;/P&gt;&lt;img src ="http://www.styledesign.biz/weblogs/macinnesm/aggbug/192.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Marcus Mac Innes</dc:creator><title>TechEd 2004 Europe - Day 3</title><link>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/07/05/179.aspx</link><pubDate>Mon, 05 Jul 2004 12:07:00 GMT</pubDate><guid>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/07/05/179.aspx</guid><wfw:comment>http://www.styledesign.biz/weblogs/macinnesm/comments/179.aspx</wfw:comment><comments>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/07/05/179.aspx#Feedback</comments><slash:comments>355</slash:comments><wfw:commentRss>http://www.styledesign.biz/weblogs/macinnesm/comments/commentRss/179.aspx</wfw:commentRss><trackback:ping>http://www.styledesign.biz/weblogs/macinnesm/services/trackbacks/179.aspx</trackback:ping><description>&lt;P&gt;Following on from my previous &lt;A href="http://www.styledesign.biz/weblogs/macinnesm/archive/2004/07/05/178.aspx"&gt;blog&lt;/A&gt;, the highlights of day 3 had to be my friend &lt;A href="http://blogs.msdn.com/bobrien/"&gt;Bill O'Brien's&lt;/A&gt; talk on &lt;A href="http://blogs.msdn.com/bobrien/archive/2004/06/25/165632.aspx"&gt;Patterns in the Enterprise (ARC309)&lt;/A&gt; and &lt;A href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=88f05a10-a1ff-49d6-87c7-c4d7b501bb02"&gt;Clemens Vasters&lt;/A&gt;' Best Practices for Dealing with State at&amp;nbsp;Multiple Layers Within Your .NET Applications (CTS404).&lt;/P&gt;
&lt;P&gt;Bill took the audience on a journey of software development, carefully explaining key concepts from the ground up. He discussed the real life difficulties of "code re-use", the Holy Gail of software development and suggested a much better take home, "knowledge re-use". Using Patterns he explained, member's of the team have a whole new vocabulary with which they are able to communicate vast amounts of information in a single sentence. &lt;/P&gt;
&lt;P&gt;Bill went on to give some real life examples of&amp;nbsp;well known patterns such as Model View Controller (MVC) and Factory, before introducing some less well known &lt;A href="http://www.eaipatterns.com/"&gt;Enterprise Patterns&lt;/A&gt; such as &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/intpatt.asp"&gt;Integration&lt;/A&gt; and &lt;A href="http://msdn.microsoft.com/architecture/patterns/default.aspx?pull=/library/en-us/dnpatterns/html/Esp.asp"&gt;Enterprise Solution&lt;/A&gt;. Using Microsoft's pattern diagram, Bill explained where patterns fit in relation to one another and how they can be grouped into "clusters" which provide assistance in making more informed choices. Overall a very difficult topic, delivered with excellence!&lt;/P&gt;
&lt;P&gt;Clemens did his usual wizardry on the audience and gave everyone good reasons to bow down to anything he might say regarding COM+. His talk was on State Management and started out by explaining why there was no such thing as "Stateless". While everyone is told over and over again that keeping state is "bad", he explained why keeping state is often "good". In a clever observation, he explained some of the internals of the Garbage Collector and why not using session state is wasteful since the data is more than likely still around from the previous call, waiting to be garbage collected.&lt;/P&gt;
&lt;P&gt;He backed this up with an example of using .NET  &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemWeakReferenceClassTopic.asp"&gt;Weak References&lt;/A&gt; to tentatively hold on to objects in Session State. This has got to be the cleverest piece of code I have seen so far at the conference and as usual, Clemen's code examples are not lightweight, they are always production quality.&lt;/P&gt;
&lt;P&gt;These and other code examples from Clemens, including very clever and best practice use of COM+ are going to be made available in the forthcoming release of &lt;A href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=d12b4ab8-d615-4c6c-90ed-5e77a830e6ea"&gt;Proseware&lt;/A&gt;.&lt;/P&gt;&lt;img src ="http://www.styledesign.biz/weblogs/macinnesm/aggbug/179.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Marcus Mac Innes</dc:creator><title>TechEd 2004 Europe - Day 2</title><link>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/07/05/178.aspx</link><pubDate>Mon, 05 Jul 2004 11:22:00 GMT</pubDate><guid>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/07/05/178.aspx</guid><wfw:comment>http://www.styledesign.biz/weblogs/macinnesm/comments/178.aspx</wfw:comment><comments>http://www.styledesign.biz/weblogs/macinnesm/archive/2004/07/05/178.aspx#Feedback</comments><slash:comments>403</slash:comments><wfw:commentRss>http://www.styledesign.biz/weblogs/macinnesm/comments/commentRss/178.aspx</wfw:commentRss><trackback:ping>http://www.styledesign.biz/weblogs/macinnesm/services/trackbacks/178.aspx</trackback:ping><description>&lt;P&gt;Following on from &lt;A href="http://www.styledesign.biz/weblogs/macinnesm/archive/2004/06/29/175.aspx"&gt;yesterday&lt;/A&gt;, &lt;A href="http://weblogs.asp.net/fbouma/archive/2004/07/01/171035.aspx"&gt;Frans Bouma&lt;/A&gt;&amp;nbsp;MVP creator of &lt;A href="http://www.llblgen.com/"&gt;LLBLGen Pro&lt;/A&gt; gave his long anticipated BOF (BOF003) session today on Object Relational (O/R) Mapping using .NET. &lt;/P&gt;
&lt;P&gt;Most of the people attending were probably still in shock over the delay / cancellation of Objectspaces in .NET 2.0 and were looking to see what alternatives were available. In good honest tradition, Thomas Tomiczek MVP creator of &lt;A href="http://www.thona-consulting.com/content/products/entitybroker.aspx"&gt;EntityBroker&lt;/A&gt; gave everyone a taste of his personal debating style which was&amp;nbsp;not dissimilar from his infamous online approach. Thomas however is one clever guy and made no mistakes in what he was saying. Meeting him in person and having in depth discussions with him afterwards made me realise that he is after all, one hell of a nice guy despite what your read in the newsgroups!&lt;/P&gt;
&lt;P&gt;There was a consensus of confusion surrounding where exactly O/R mappers are required. Some advocated the use of hybrid systems (which I do not recommend) which combine O/R mapping layers with faster direct database access methods for read only operations. While this *might* achieve better performance, you have to way up the cost of loosing maintainability and database independence.&lt;/P&gt;
&lt;P&gt;Well done Frans on a lively and rounded debate.&lt;/P&gt;&lt;img src ="http://www.styledesign.biz/weblogs/macinnesm/aggbug/178.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>