Today I encountered a weird issue in our multi-threaded .NET application.
I was writing a public static event accessor like so:
private static readonly object myLock = new object();
private static Action<MyType, Guid, Guid> _handler;
public static event Action<MyType, Guid, Guid> MyEvent
{
add { lock (myLock) _handler += value; }
remove { lock (myLock) _handler -= value; }
}
This piece of code lives in a a non static class.
The issue I face is that once I use the add accessor (at a rather early point of the execution of the application): MyClass.MyEvent += myMethod;
, I get a null reference exception in the lock method call in the add accessor. Through debugging I found out that this is because, for some reason, the private static lock object is (still) null at the point the code reaches the lock statement.
This is baffling to me. My understanding is that all static members should be initialized at the point of the first access to the class? I later did realize, that the code seems to work if I move the lock object to the top of the class, meaning it gets initialized at an way earlier point. This works, but I would like to keep all relevant code in one place, so I don't like this solution.
FYI, the file I am working in has almost 5000 lines of code, and the snippet above is close to the end. I have no idea if that makes any difference though...
A theory of ours has been that the problem has to do with the fact that we are working with several threads. More precise than that, we have not figured out. It feels a bit silly that this would be the cause of or problem, as the reason we want to use a static event accessor with locks is to handle multi-thread access...
UPDATE
So it turns out it now suddenly just works. As it should.
I honestly have no idea what the problem nor the fix was. I simply went on with my day and implemented a few other static event fields as well as subscribing to these from another file. Having recompiled the project it now works as it should. I did not edit the order of the statements in the file btw.
Thank you all for all your suggestions, thoughts and information. I realise the manner of this implementation (public static event) may not be optimal, but it was the route chosen for this implementation for the moment.