public WeakReference(ReferenceCountedDisposable <T> reference) : this() { if (reference == null) { throw new ArgumentNullException(nameof(reference)); } var instance = reference._instance; var referenceCount = reference._boxedReferenceCount; if (instance == null) { // The specified reference is already not valid. This case is supported by WeakReference (not // unlike `new System.WeakReference(null)`), but we return early to avoid an unnecessary // allocation in this case. // // ⚠ Note that in cases where referenceCount._weakInstance is already non-null, it would be // possible to reconstruct a strong reference even though the current reference instance was // disposed. This case is intentionally not supported (by checking 'instance' before checking // 'referenceCount._weakInstance'), since it would be confusing semantics if this constructor // sometimes worked from a disposed reference and sometimes did not. return; } // We only need to allocate a new WeakReference<T> for this reference if one has not already been // created for it. LazyInitialization.EnsureInitialized(ref referenceCount._weakInstance, static instance => new WeakReference <T>(instance), instance); _boxedReferenceCount = referenceCount; }
public IReferenceCountedDisposable <ICacheEntry <TKey, TValue> > GetOrCreate(TKey key, Func <TKey, TValue> valueCreator) { lock (_gate) { ReferenceCountedDisposable <Entry> disposable = null; // If we already have one in the map to hand out, great if (_cache.TryGetValue(key, out var weakReference)) { disposable = weakReference.TryAddReference(); } if (disposable == null) { // We didn't easily get a disposable, so one of two things is the case: // // 1. We have no entry in _cache at all for this. // 2. We had an entry, but it was disposed and is no longer valid. This could happen if // the underlying value was disposed, but _cache hasn't been updated yet. That could happen // because the disposal isn't processed under this lock. // In either case, we'll create a new entry and add it to the map disposable = new ReferenceCountedDisposable <Entry>(new Entry(this, key, valueCreator(key))); _cache[key] = new ReferenceCountedDisposable <Entry> .WeakReference(disposable); } return(disposable); } }
public WeakReference(ReferenceCountedDisposable <T> reference) : this() { if (reference == null) { throw new ArgumentNullException(nameof(reference)); } var instance = reference._instance; var referenceCount = reference._boxedReferenceCount; if (instance == null) { // The specified reference is already not valid. This case is supported by WeakReference (not // unlike `new System.WeakReference(null)`), but we return early to avoid an unnecessary // allocation in this case. return; } _weakInstance = new WeakReference <T>(instance); _boxedReferenceCount = referenceCount; }