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); } }
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); } } }