예제 #1
0
 public QualityMessage GetValue(SolutionMessage message, Evaluator evaluate, ExtensionRegistry extensions) {
   var entry = new CacheEntry(message.ToString());
   bool lockTaken = false;
   bool waited = false;
   try {
     Monitor.Enter(cacheLock, ref lockTaken);
     while (true) {
       LinkedListNode<CacheEntry> node;
       if (index.TryGetValue(entry, out node)) {
         list.Remove(node);
         list.AddLast(node);
         Hits++;
         lockTaken = false;
         Monitor.Exit(cacheLock);
         OnChanged();
         return node.Value.GetMessage(extensions);
       } else {
         if (!waited && activeEvaluations.Contains(entry.Key)) {
           while (activeEvaluations.Contains(entry.Key))
             Monitor.Wait(cacheLock);
           waited = true;
         } else {
           activeEvaluations.Add(entry.Key);
           lockTaken = false;
           Monitor.Exit(cacheLock);
           OnChanged();
           try {
             entry.SetMessage(evaluate(message));
             Monitor.Enter(cacheLock, ref lockTaken);
             index[entry] = list.AddLast(entry);
             Trim();
           } finally {
             if (!lockTaken)
               Monitor.Enter(cacheLock, ref lockTaken);
             activeEvaluations.Remove(entry.Key);
             Monitor.PulseAll(cacheLock);
             lockTaken = false;
             Monitor.Exit(cacheLock);
           }
           OnChanged();
           return entry.GetMessage(extensions);
         }
       }
     }
   } finally {
     if (lockTaken)
       Monitor.Exit(cacheLock);
   }
 }
예제 #2
0
        public QualityMessage GetValue(SolutionMessage message, Evaluator evaluate, ExtensionRegistry extensions)
        {
            var  entry     = new CacheEntry(message.ToString());
            bool lockTaken = false;
            bool waited    = false;

            try {
                Monitor.Enter(cacheLock, ref lockTaken);
                while (true)
                {
                    LinkedListNode <CacheEntry> node;
                    if (index.TryGetValue(entry, out node))
                    {
                        list.Remove(node);
                        list.AddLast(node);
                        Hits++;
                        lockTaken = false;
                        Monitor.Exit(cacheLock);
                        OnChanged();
                        return(node.Value.GetMessage(extensions));
                    }
                    else
                    {
                        if (!waited && activeEvaluations.Contains(entry.Key))
                        {
                            while (activeEvaluations.Contains(entry.Key))
                            {
                                Monitor.Wait(cacheLock);
                            }
                            waited = true;
                        }
                        else
                        {
                            activeEvaluations.Add(entry.Key);
                            lockTaken = false;
                            Monitor.Exit(cacheLock);
                            OnChanged();
                            try {
                                entry.SetMessage(evaluate(message));
                                Monitor.Enter(cacheLock, ref lockTaken);
                                index[entry] = list.AddLast(entry);
                                Trim();
                            } finally {
                                if (!lockTaken)
                                {
                                    Monitor.Enter(cacheLock, ref lockTaken);
                                }
                                activeEvaluations.Remove(entry.Key);
                                Monitor.PulseAll(cacheLock);
                                lockTaken = false;
                                Monitor.Exit(cacheLock);
                            }
                            OnChanged();
                            return(entry.GetMessage(extensions));
                        }
                    }
                }
            } finally {
                if (lockTaken)
                {
                    Monitor.Exit(cacheLock);
                }
            }
        }