Ejemplo n.º 1
0
        /// <summary>
        /// Declares the key is going to be computed.
        /// It blocks the caller if there is another thread computing that key. When that other thread finishes,
        /// this thread is released and returned false. the caller is expected to get the item from the cache
        /// then (and caller must assume the object may be removed -unlikely but possible- by the time the caller tries to retrieve it).
        /// If the method returns true, the caller to invoke "Complete" once it adds the element to the cache.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <returns><c>true</c> if true, the key doesn't have a value and is not being computed yet<c>false</c> otherwise.</returns>
        public bool StartInflight(TKey key)
        {
            EventAndCount ev = null;

            lock (this.inflight)
            {
                if (!this.inflight.TryGetValue(key, out ev))
                {
                    this.inflight.Add(key, null);
                }
                else
                {
                    if (ev == null)
                    {
                        ev = new EventAndCount();
                        this.inflight[key] = ev;
                    }
                }
            }

            if (ev == null)
            {
                return(true);
            }

            ev.WaitAndReturnIfLast();

            return(false);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Completes the inflight operation to the specified key.
        /// This method needs to be invoked right after the Add or TryAdd call if the caller invoked "Inflight".
        /// </summary>
        /// <param name="key">The key just added.</param>
        /// <exception cref="System.InvalidOperationException">Complete was invoked without a corresponding Inflight call</exception>
        public void CompleteInflight(TKey key)
        {
            lock (this.inflight)
            {
                EventAndCount ev = null;
                if (!this.inflight.TryGetValue(key, out ev))
                {
                    throw new InvalidOperationException("Complete was invoked without a corresponding Inflight call");
                }

                this.inflight.Remove(key);

                // if anybody was waiting on this, now we tell them.
                ev?.Set();
            }
        }