Fix potential thread-safety issue

This commit is contained in:
Dean Herbert 2018-09-06 13:27:53 +09:00
parent 8d9e0ff1c3
commit 89a92ab7eb
1 changed files with 7 additions and 19 deletions

View File

@ -199,7 +199,7 @@ public class RecyclableLazy<T>
private readonly Func<T> valueFactory;
private readonly Func<T, bool> stillValidFunction;
private readonly object initLock = new object();
private readonly object fetchLock = new object();
public RecyclableLazy(Func<T> valueFactory, Func<T, bool> stillValidFunction = null)
{
@ -223,29 +223,17 @@ public T Value
{
get
{
recreateIfInvalid();
return lazy.Value;
lock (fetchLock)
{
if (!stillValid)
recreate();
return lazy.Value;
}
}
}
private bool stillValid => lazy.IsValueCreated && (stillValidFunction?.Invoke(lazy.Value) ?? true);
private void recreateIfInvalid()
{
lock (initLock)
{
if (!lazy.IsValueCreated)
// we have not yet been initialised or haven't run the task.
return;
if (stillValid)
// we are still in a valid state.
return;
recreate();
}
}
private void recreate() => lazy = new Lazy<T>(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication);
}
}