/// <inheritdoc /> public async Task <IPinnedValue <TKey, TValue> > GetPinAsync(TKey key, TState state) { IAsyncCacheContracts.GetPinAsync(this, key); while (true) { try { var entry = await this.entries.GetOrAddLazyAsync( key, pinKey => this.CreateCacheEntryAsync(pinKey, state)).DontMarshallContext(); IPinnedValue <TKey, TValue> pin; if (entry.TryPin(out pin)) { // if pin was successful return the pin, otherwise loop back and try again // (pinning can fail if the cache entry is being disposed by another thread) return(pin); } } catch (Exception) { // if creating the cache value threw an exception remove it from the dictionary // otherwise exceptions could slowly fill in the cache, aka memory leak this.entries.TryRemove(key); throw; } } }
/// <inheritdoc /> public async Task <IPinnedValue <TKey, TChunk> > GetPinAsync(TKey key) { IAsyncCacheContracts.GetPinAsync(this, key); if (this.isInBounds(key)) { return(await this.cache.GetPinAsync(key).DontMarshallContext()); } else { return(new FakePin(key, this.outOfBounds.Create(key))); } }
/// <inheritdoc /> public Task <IPinnedValue <TKey, TValue> > GetPinAsync(TKey key) { IAsyncCacheContracts.GetPinAsync(this, key); return(this.cache.GetPinAsync(key, default(VoidStruct))); }