<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.iis.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:cs="http://blogs.iis.net/"><channel><title>Tobin Titus Blog : Threading</title><link>http://blogs.iis.net/tobintitus/archive/tags/Threading/default.aspx</link><description>Tags: Threading</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Unsafe thread safety</title><link>http://blogs.iis.net/tobintitus/archive/2006/10/05/Unsafe-thread-safety.aspx</link><pubDate>Thu, 05 Oct 2006 07:42:00 GMT</pubDate><guid isPermaLink="false">50bcf3b4-f6fe-4638-adff-0c150e922e99:1417524</guid><dc:creator>TobinTitus</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.iis.net/tobintitus/rsscomments.aspx?PostID=1417524</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.iis.net/tobintitus/commentapi.aspx?PostID=1417524</wfw:comment><comments>http://blogs.iis.net/tobintitus/archive/2006/10/05/Unsafe-thread-safety.aspx#comments</comments><description>&lt;p&gt;As I stated in my last post, for the past two days I&amp;#39;ve been sitting in Jeffrey Richter&amp;#39;s threading class.&amp;nbsp;The class is near the end and I can&amp;#39;t say that a lot of new concepts have been taught. Another student and I have decided that the class should have been renamed, &amp;quot;Threading Basics&amp;quot;. That&amp;#39;s not to say anything of Richter&amp;#39;s teaching skill or the content of the class.&amp;nbsp; It just goes to show that if the architecture of a product is right, the threading code should be extremely simple to use.&lt;/p&gt;&lt;p&gt;However, what I love about this class is that it reminds me how much I enjoy this topic.&amp;nbsp; The theory of the perfect architecture doesn&amp;#39;t exist. Additionally, many times the developer has little-to-no ability to push back on a bad&amp;nbsp;architecture. It&amp;#39;s in these cases that you must use your bag of concurrency tricks to work out of the whole the architect(s) put you in.&amp;nbsp; That sound easy enough, but what if the architecture included - *gasp* - &amp;quot;less-than-optimal&amp;quot; decisions in the actual .NET framework classes?&amp;nbsp; What if those decisions were made in the very methods that are supposed to help you with these synchronization problems?&amp;nbsp; These problems perplexed me when I first encountered them and I never really thought to blog about them (I was actually just scared I was doing something wrong).&amp;nbsp; Taking this class gave me the perfect excuse to bring the topic up.&lt;/p&gt;&lt;p&gt;Take a look at the following pattern in C++:&lt;/p&gt;&lt;pre&gt;&lt;font face="courier"&gt;class CConcurrencySample
{
public:
    CConcurrencySample( ) 
    {   // Initialize a critical section on class construction
        InitializeCriticalSection( &amp;amp;m_criticalSection );
    };
    ~CConcurrencySample( ) 
    {   // Destroy the critical section on class destruction
        DeleteCriticalSection( &amp;amp;m_criticalSection );
    };

    // This method is over-simplified on purpose
    ////////////////////////////////////////////////////////////
    BOOL SafeMethod( )
    {
        // Claim ownership of the critical section
        if( ! TryEnterCriticalSection( &amp;amp;m_criticalSection ) )
        {
            return FALSE; 
        }

        ////////////////////////////////////////////////
        // Thread-safe code goes here
        ////////////////////////////////////////////////

        // Release ownership of the critical section
        LeaveCriticalSection( &amp;amp;m_criticalSection );

        return TRUE;
    };
private:
    CRITICAL_SECTION m_criticalSection;
};
&lt;/font&gt;&lt;/pre&gt;&lt;p&gt;Anyone that&amp;#39;s done any work in threading recognizes this pattern.&amp;nbsp; We&amp;#39;ve declared a class named &lt;strong&gt;CConcurrencySample&lt;/strong&gt;.&amp;nbsp; When any code instantiates an instance of &lt;strong&gt;CConcurrencySample&lt;/strong&gt;, the constructor initializes the private &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/critical_section_objects.asp" title="CRITICAL_SECTION"&gt;CRITICAL_SECTION&lt;/a&gt;&lt;/strong&gt; instance in the object. When any code destroys an instance of &lt;strong&gt;CConcurrencySample&lt;/strong&gt;, the &lt;strong&gt;CRITICAL_SECTION&lt;/strong&gt; is also deleted. With this pattern, we know that all members have access to the critical section and can claim ownership of the critical section at any point.&amp;nbsp; For my purposes, I&amp;#39;ve created a method named &lt;strong&gt;SafeMethod&lt;/strong&gt; that will take the critical section lock when it is called, and release the lock when it leaves the method.&amp;nbsp; The good part about this pattern is that each instance has a way to lock &lt;strong&gt;SafeMethod&lt;/strong&gt;. The downside is that if client doesn&amp;#39;t need to call &lt;strong&gt;SafeMethod&lt;/strong&gt;, then the &lt;strong&gt;CRITICAL_SECTION&lt;/strong&gt; is created, initialized and destroyed without need -- uselessly taking up memory (24 bytes on a 32bit OS) and processor cycles.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The CLR implemented this pattern and even expanded on it.&amp;nbsp;They also tried to fix the waste incurred with non-use of the critical section.&amp;nbsp; The CLR implementation works as follows.&amp;nbsp; Each System.Object created by the CLR contains a sync block index (4 bytes on a 32bit OS) that is defaulted to -1.&amp;nbsp; If a critical section is entered within the object, the CLR adds the object&amp;#39;s sync block to an array and sets the object&amp;#39;s sync block index to the position in the array.&amp;nbsp; With me so far?&amp;nbsp; So how does one enter a critical section in .NET? Using the &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemthreadingmonitorclasstopic.asp" title="Monitor"&gt;Monitor&lt;/a&gt;&lt;/strong&gt; class, of course.&amp;nbsp; The following example emulates the same functionality as the previous C++ sample by using C#.&lt;/p&gt;&lt;pre&gt;&lt;font face="Courier"&gt;
public class CConcurrencySample
{
   bool SafeMethod( )
   {
      // Claim ownership of the critical section
      if( Monitor.TryEnter( this ) )
      {
          return false;
      }

      ////////////////////////////////////////////////
      // Thread-safe code goes here
      ////////////////////////////////////////////////
    		
      // Release ownership of the critical section
      Monitor.Exit( this );

      return true;
    }
}&lt;/font&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemthreadingmonitorclasstopic.asp" title="Monitor.Enter"&gt;Monitor.Enter&lt;/a&gt;&lt;/strong&gt; and &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemthreadingmonitorclasstopic.asp" title="Monitor.Exit"&gt;&lt;strong&gt;Monitor.Exit&lt;/strong&gt;&lt;/a&gt;&amp;nbsp;are supposed to provide similar functionality of entering and leaving a critical section (respectively). Since all &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemobjectclasstopic.asp" title="System.Object"&gt;System.Object&lt;/a&gt;&lt;/strong&gt;&amp;#39;s have their own &lt;strong&gt;SyncBlock&lt;/strong&gt;, we just need to pass our current object to the &lt;strong&gt;Monitor.Enter&lt;/strong&gt; and &lt;strong&gt;Monitor.Exit&lt;/strong&gt; method. This performs the lock I described earlier by setting the sync block index.&amp;nbsp; Sounds great, but what&amp;#39;s the difference between that C++ example and the C# pattern?&amp;nbsp; What issue can you see in the .NET framework implementation of this pattern that you don&amp;#39;t see in the C++ sample I provided?&lt;/p&gt;&lt;p&gt;Give up?&lt;/p&gt;&lt;p&gt;The answer simple. In the C++ sample, the lock object (the &lt;strong&gt;CRITICAL_SECTION&lt;/strong&gt; field) is private. This means that no external clients can lock my object.&amp;nbsp; My object controls the locks.&amp;nbsp; In the .NET implementation, &lt;strong&gt;Monitor.Enter&lt;/strong&gt; can take ANY object. ANY caller can lock on ANY object. External clients locking on your object&amp;#39;s SyncBlock can cause a deadlock.&lt;/p&gt;&lt;pre&gt;&lt;font face="Courier"&gt;
    public class CConcurrencySample2
    {
        private Object m_lock = null;

        bool SafeMethod ( )
        {
            if ( m_lock == null )
            {
                m_lock = new Object( );
            }
            if ( ! Monitor.TryEnter( m_lock ) )
            {
                return false;
            }

            ////////////////////////////////////////////////
            // Thread-safe code goes here
            ////////////////////////////////////////////////

            Monitor.Exit( m_lock );

            return true;
        }
    }
&lt;/font&gt;&lt;/pre&gt;&lt;p&gt;With this approach, we are declaring an plain, privately-declared object in the class.&amp;nbsp; Be careful when using this approach that you don&amp;#39;t use a value-type for your private lock.&amp;nbsp; Value type&amp;#39;s passed to a Monitor will be boxed each time the methods on Monitor is called and a new SyncBlock is used -- effectively making the lock useless.&amp;nbsp; &lt;/p&gt;&lt;p&gt;So what does this have to do with IIS?&amp;nbsp; Nothing just yet. But I plan to cover some asynchronous web execution patterns in future posts and I figured this would be a great place to start.&amp;nbsp; &lt;/p&gt;&lt;p&gt;This information is pretty old but sitting in class I realized it might not be completely obvious to everyone just yet.&amp;nbsp; If you were someone in-the-know about this information since WAY back in 2002, please forgive the repitition.&lt;/p&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=1417524" width="1" height="1"&gt;</description><category domain="http://blogs.iis.net/tobintitus/archive/tags/Threading/default.aspx">Threading</category><category domain="http://blogs.iis.net/tobintitus/archive/tags/Asynchronous/default.aspx">Asynchronous</category></item></channel></rss>