Is there any way I can call this getter and consistently get the expected result?

c#, locking, multithreading, race-condition

Solution

Am I correct to believe that whenever _myProperty is null, the getter calls the setter and there's a race condition bug here that may be causing the random/occasional freezing I'm experiencing? How can I confirm/infirm that this freezing is effectively a deadlock?

No. In C#, `lock` is reentrant for the same thread. You can see this in the documentation for Monitor.Enter:

It is legal for the same thread to invoke Enter more than once without it blocking; however, an equal number of Exit calls must be invoked before other threads waiting on the object will unblock.

don't like the Locker being publicly accessible either, sounds like asking for trouble

I agree with you here. This is more likely the culprit. The fact that `Locker` is public most likely means that something else in the library is locking on this object, which could be the cause of the deadlock.

If you can run this through the Visual Studio Concurrency Profiler, you should be able to pause at the deadlock, and see the objects blocking at that point in time.

Problem

I need to use a property getter from a 3rd-party API, and just accessing that getter sometimes hangs the entire application, sometimes works (in dev/debugger). And if I deploy it to a production server, the host application sometimes works as expected, sometimes dies with an APPCRASH in KERNEL32. I couldn't understand how a simple getter could freeze up or crash anything, so I though maybe that property was a method in disguise, and used my favorite decompiler to find out. This is the scheme/pattern I came across: ``` internal MyClass() : ISomeInterface { Locker = new object(); } public object Locker { get; private set; } private SomeObject _myProperty; public SomeObject MyProperty { get { lock (Locker) { if (_myProperty== null) MyProperty = SomeCondition ? SomeMethod() : Something.Else; return _myProperty; } } private set { _myProperty = value; } } ``` Am I correct to believe that whenever `_myProperty` is `null`, the getter calls the setter and there's a race condition bug here that may be causing the random/occasional freezing I'm experiencing? How can I confirm/infirm that this freezing is effectively a deadlock? What would be a correct implementation? I'm led to believe that if the setter also had a `lock (Locker)` (I don't like the `Locker` being publicly accessible either, sounds like asking for trouble), and the getter would assign `_myProperty` instead of calling the setter, it'd be thread-safe. Lastly, is there a way I can call this getter without requiring the 3rd party to ship a "fixed" version, and without freezing? I have tried calling it from the main UI thread, I have tried calling it from a `Task` / background thread, I have tried a `Sleep(200)` before the call, I have tried setting a timeout on the `Task`... no matter what I do, I don't seem to be able to consistently call that getter and reliably get the expected result (it does work... sometimes). The `Locker` object is public, but it's defined in an `internal class` that I only access via its interface, which of course doesn't expose it. Is there a way I can use reflection to acquire the lock from the outside (`Monitor.TryEnter(magicallyObtainedLocker)`) and actually get it to work? Or is that getter completely borked?

Original source