6

Where Sessions is a Dictionary<Guid, WebSession>, and NewSession is new WebSession() I have this line:

Sessions.Add(NewSession.SessionID, NewSession);

Now at this point you're probably rolling your eyeballs and thinking "well either Sessions is null, or NewSession.SessionID is null." However:

Sessions == null
false
NewSession.SessionID == null
false
NewSession == null
false

It's pretty intermittent. Happens maybe one time in 50. And whenever it happens, I can just do Sessions.Add(NewSession.SessionID, NewSession); in the immediate window and it works fine.

The constructor for WebSession is synchronous, and Sessions is a vanilla dictionary with no added sugar.

I'm pretty sure I've done due diligence at this point. It's a harmless enough thing to happen in my application and it's trapped and handled cleanly - but I'm stumped as to what causes it in the first place.

Edit: I'm wondering if it's because my WebSession inherits : Dictionary<String, Object> but its constructor doesn't call base() - that still wouldn't explain it though since I can check that the object isn't null before doing Add(..)

PhonicUK
  • 12,412
  • 3
  • 36
  • 61
  • possible duplicate of [What is a NullReferenceException in .NET?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net) –  Mar 03 '13 at 19:10
  • what about showing a stack-trace? usually this unveils everything ... –  Mar 03 '13 at 19:11
  • Add some asserts with messages so that the message tells you what exactly was null. – usr Mar 03 '13 at 19:11
  • The stack trace shows nothing useful except it going inside `Sessions.Add` and `Sessions.Insert` - the Insert is where the NRE occurs. – PhonicUK Mar 03 '13 at 19:13
  • @usr - it's in .net framework code that the exception is happening, not mine. I can check beforehand that nothing is null and it's fine. – PhonicUK Mar 03 '13 at 19:14
  • 3
    Oh ok then it is a threading bug. A Dictionary does not have bugs. Neither does a Guid. It is a threading problem which causes some internal stuff to be null at unexpected times. – usr Mar 03 '13 at 19:16
  • @usr exactly my thought :) ... the thing "happens 1 out of 50" makes it very suspicious ... –  Mar 03 '13 at 19:17
  • Actually, if you had posted the stack trace this would have been easy to prove right away. – usr Mar 03 '13 at 19:18
  • I'll try and grab an actual strace, may take a while being a 1-in-50 thing though. – PhonicUK Mar 03 '13 at 19:19

1 Answers1

7

You need to use a thread-safe collection such as ConcurrentDictionary, or implement your own sychronization.

Attempting to access a Dictionary<TKey,TValue> from multiple threads can result in heisenbugs, which may well manifest themselves as a NullReferenceException.

Joe
  • 114,633
  • 27
  • 187
  • 321