What is the thread safe way to dispose a lazy-initialized object in C#? Suppose I have the following Lazy
construct:
Lazy<MyClass> lazy = new Lazy<MyClass>(() => MyClass.Create(), true);
Later, I might want to dispose the MyClass
instance created. Most existing solutions recommend something like this:
if (lazy.IsValueCreated)
{
lazy.Value.Dispose();
}
But as far as I can tell IsValueCreated
does not hold any locks: https://referencesource.microsoft.com/#mscorlib/system/Lazy.cs,284
This means another thread may be in the process of initializing MyClass
when we check for IsValueCreated
. In that case we will observe IsValueCreated
to be false, and end up leaking a resource. What is the right course of action here? Or have I missed some subtle detail?
This means another thread may be in the process of initializing MyClass
. I think this is a typical problem of any multi-threading application where resources are shared between the threads. You can build your own locks or take a good look at your object's lifetime. Even if you would be able to lock theIsValueCreated
, you might still have an issue while accessing it in the middle of your dispose operation. – GeigerIsValueCreated
takes a lock or not is only one issue you might have. If this is your shot at disposing the object, if no thread is currently about to initialize it, if it were to do that later, after you've run the dispose-code (which thus didn't dispose of anything) you won't dispose of that. If the object is there when the dispose-code is running you will dispose of it, but the lazy-object will still hold a reference to the now disposed object. In short, you cannot run your dispose code until you've guaranteed no such thread is either executing or going to execute later. – Patagium