title: Null reference in multithreading test
body: <p>I have been working through <a href="http://nhibernate.info/doc/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.html" rel="nofollow">this article</a> from the NHibernate website to implement a UnitOfWork pattern, and I have run into a problem I haven't been able to solve. In section 3, which is where the implementation is being made thread safe, there is a test which is throwing a null reference exception. I have no experience with multi-threading, so I'm not sure how to proceed here. </p>
  
  <p>Can you tell me what the problem is?</p>
  
  <p><strong>Test code</strong></p>
  
  <pre><code>private ManualResetEvent _event;
  
  [Test]
  public void Local_data_is_thread_local()
  {
      Console.WriteLine("Starting in main thread {0}", Thread.CurrentThread.ManagedThreadId);
      Local.Data["one"] = "This is a string";
      Assert.AreEqual(1, Local.Data.Count);
  
      _event = new ManualResetEvent(false);
      var backgroundThread = new Thread(RunInOtherThread);
      backgroundThread.Start();
  
      // give the background thread some time to do its job
      Thread.Sleep(100); &lt;&lt;&lt;&lt;&lt;&lt;&lt; ######## EXCEPTION AFTER THIS LINE #########
      // we still have only one entry (in this thread)
      Assert.AreEqual(1, Local.Data.Count);
  
      Console.WriteLine("Signaling background thread from main thread {0}", Thread.CurrentThread.ManagedThreadId);
      _event.Set();
      backgroundThread.Join();
  }
  
  private void RunInOtherThread()
  {
      Console.WriteLine("Starting (background-) thread {0}", Thread.CurrentThread.ManagedThreadId);
      // initially the local data must be empty for this NEW thread!
      Assert.AreEqual(0, Local.Data.Count);
      Local.Data["one"] = "This is another string";
      Assert.AreEqual(1, Local.Data.Count);
  
      Console.WriteLine("Waiting on (background-) thread {0}", Thread.CurrentThread.ManagedThreadId);
      _event.WaitOne();
      Console.WriteLine("Ending (background-) thread {0}", Thread.CurrentThread.ManagedThreadId);
  }
  </code></pre>
  
  <p><strong>Code being tested</strong></p>
  
  <pre><code>public interface ILocalData
  {
      object this[object key] { get; set; }
      int Count { get; }
      void Clear();
  }
  
  public static class Local
  {
      static readonly ILocalData _data = new LocalData();
  
      public static ILocalData Data
      {
          get { return _data; }
      }
  
      private class LocalData : ILocalData
      {
          [ThreadStatic]
          private static Hashtable _localData = new Hashtable();
  
          public object this[object key]
          {
              get { return _localData[key]; }
              set { _localData[key] = value; }
          }
  
          public int Count
          {
              get { return _localData.Count; } &lt;&lt;&lt;&lt;&lt;&lt;&lt; ######## EXCEPTION HERE #########
          }
  
          public void Clear()
          {
              _localData.Clear();
          }
      }
  }
  </code></pre>
  
  <p>Technically, the tests pass, but in the output, I can see that there is a null reference exception:</p>
  
  <pre><code>Run started: C:\Users\brainbolt\Documents\GitHub\NHibernateUnitOfWork\NHinbernateUnitOfWork.Testing\bin\Debug\NHinbernateUnitOfWork.Testing.dll
  Starting in main thread 18
  Starting (background-) thread 19
  System.NullReferenceException: Object reference not set to an instance of an object.
     at NHibernateUnitOfWork.NHibernateUnitOfWork.Local.LocalData.get_Count() in c:\Users\brainbolt\Documents\GitHub\NHibernateUnitOfWork\NHibernateUnitOfWork\Local.cs:line 37
     at NHinbernateUnitOfWork.Testing.LocalData_Fixture.RunInOtherThread() in c:\Users\brainbolt\Documents\GitHub\NHibernateUnitOfWork\NHinbernateUnitOfWork.Testing\LocalData_Fixture.cs:line 73
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
     at System.Threading.ThreadHelper.ThreadStart()
     at NHibernateUnitOfWork.NHibernateUnitOfWork.Local.LocalData.get_Count() in c:\Users\brainbolt\Documents\GitHub\NHibernateUnitOfWork\NHibernateUnitOfWork\Local.cs:line 37
     at NHinbernateUnitOfWork.Testing.LocalData_Fixture.RunInOtherThread() in c:\Users\brainbolt\Documents\GitHub\NHibernateUnitOfWork\NHinbernateUnitOfWork.Testing\LocalData_Fixture.cs:line 73
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
     at System.Threading.ThreadHelper.ThreadStart()
  Signaling background thread from main thread 18
  NUnit VS Adapter 2.0.0.0 executing tests is finished
  </code></pre>