Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Common / Utils / Memoizer.cs / 1305376 / Memoizer.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System.Collections.Generic; using System.Threading; using System.Diagnostics; namespace System.Data.Common.Utils { ////// Remembers the result of evaluating an expensive function so that subsequent /// evaluations are faster. Thread-safe. /// ///Type of the argument to the function. ///Type of the function result. internal sealed class Memoizer{ private readonly Func _function; private readonly Dictionary _resultCache; private readonly ReaderWriterLockSlim _lock; /// /// Constructs /// /// Required. Function whose values are being cached. /// Optional. Comparer used to determine if two functions arguments /// are the same. internal Memoizer(Funcfunction, IEqualityComparer argComparer) { EntityUtil.CheckArgumentNull(function, "function"); _function = function; _resultCache = new Dictionary (argComparer); _lock = new ReaderWriterLockSlim(); } /// /// Evaluates the wrapped function for the given argument. If the function has already /// been evaluated for the given argument, returns cached value. Otherwise, the value /// is computed and returned. /// /// Function argument. ///Function result. internal TResult Evaluate(TArg arg) { Result result; bool hasResult; // check to see if a result has already been computed _lock.EnterReadLock(); try { hasResult = _resultCache.TryGetValue(arg, out result); } finally { _lock.ExitReadLock(); } if (!hasResult) { // compute the new value _lock.EnterWriteLock(); try { // see if the value has been computed in the interim if (!_resultCache.TryGetValue(arg, out result)) { result = new Result(() => _function(arg)); _resultCache.Add(arg, result); } } finally { _lock.ExitWriteLock(); } } // note: you need to release the global cache lock before (potentially) acquiring // a result lock in result.GetValue() return result.GetValue(); } ////// Encapsulates a 'deferred' result. The result is constructed with a delegate (must not /// be null) and when the user requests a value the delegate is invoked and stored. /// private class Result { private TResult _value; private Func_delegate; internal Result(Func createValueDelegate) { Debug.Assert(null != createValueDelegate, "delegate must be given"); _delegate = createValueDelegate; } internal TResult GetValue() { if (null == _delegate) { // if the delegate has been cleared, it means we have already computed the value return _value; } // lock the entry while computing the value so that two threads // don't simultaneously do the work lock (this) { if (null == _delegate) { // between our initial check and our acquisition of the lock, some other // thread may have computed the value return _value; } _value = _delegate(); // ensure _delegate (and its closure) is garbage collected, and set to null // to indicate that the value has been computed _delegate = null; return _value; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MsmqProcessProtocolHandler.cs
- Grammar.cs
- SocketInformation.cs
- ValidationErrorCollection.cs
- Attributes.cs
- HashCodeCombiner.cs
- ImportFileRequest.cs
- WmlFormAdapter.cs
- SymbolEqualComparer.cs
- CachedFontFamily.cs
- TogglePatternIdentifiers.cs
- ServiceEndpoint.cs
- SourceSwitch.cs
- CompoundFileIOPermission.cs
- ToolStripMenuItem.cs
- HttpWrapper.cs
- SoapObjectReader.cs
- StylusSystemGestureEventArgs.cs
- RequestNavigateEventArgs.cs
- CodeSubDirectoriesCollection.cs
- AuthenticateEventArgs.cs
- ListenerHandler.cs
- IndentTextWriter.cs
- SystemColors.cs
- ToolBarPanel.cs
- DPTypeDescriptorContext.cs
- AnchoredBlock.cs
- TableLayoutPanelBehavior.cs
- ClosableStream.cs
- DiffuseMaterial.cs
- Nullable.cs
- WebCategoryAttribute.cs
- UserInitiatedRoutedEventPermissionAttribute.cs
- SingleStorage.cs
- InlinedAggregationOperatorEnumerator.cs
- Vector3D.cs
- XmlTextWriter.cs
- ConnectionProviderAttribute.cs
- AsyncStreamReader.cs
- HotSpotCollection.cs
- SerializationSectionGroup.cs
- CardSpaceException.cs
- DataGridCaption.cs
- IMembershipProvider.cs
- DocumentEventArgs.cs
- ListViewInsertionMark.cs
- SafeSecurityHandles.cs
- TabItemAutomationPeer.cs
- KnowledgeBase.cs
- ListViewDataItem.cs
- RecognizerStateChangedEventArgs.cs
- OrderablePartitioner.cs
- SecurityCredentialsManager.cs
- WebPartZoneCollection.cs
- DoubleIndependentAnimationStorage.cs
- WorkflowDurableInstance.cs
- WorkflowExecutor.cs
- TextRunTypographyProperties.cs
- AssemblyAttributesGoHere.cs
- MethodToken.cs
- Logging.cs
- TempEnvironment.cs
- BitmapCodecInfoInternal.cs
- SqlConnectionStringBuilder.cs
- DataGridPageChangedEventArgs.cs
- DispatcherExceptionEventArgs.cs
- BamlLocalizationDictionary.cs
- DynamicRouteExpression.cs
- DataGridHeaderBorder.cs
- RSAOAEPKeyExchangeDeformatter.cs
- Query.cs
- PrimitiveCodeDomSerializer.cs
- TextServicesDisplayAttributePropertyRanges.cs
- WindowsSysHeader.cs
- GlobalAllocSafeHandle.cs
- ConfigXmlComment.cs
- ConfigXmlText.cs
- SqlClientPermission.cs
- XmlIlTypeHelper.cs
- RuntimeCompatibilityAttribute.cs
- AbsoluteQuery.cs
- RsaSecurityToken.cs
- SelectionEditor.cs
- COM2ColorConverter.cs
- WorkflowDesigner.cs
- ObjectDataSourceFilteringEventArgs.cs
- XmlSchemaInfo.cs
- WebBrowserPermission.cs
- SourceChangedEventArgs.cs
- ItemType.cs
- ImageAutomationPeer.cs
- CultureInfoConverter.cs
- MarkupProperty.cs
- DiagnosticsConfiguration.cs
- EventDescriptor.cs
- ClientViaElement.cs
- SQLRoleProvider.cs
- EdmProperty.cs
- DataBoundControlHelper.cs
- FixedFlowMap.cs