Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Common / Utils / Memoizer.cs / 1 / 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. //---------------------------------------------------------------------- // // 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
- ProtocolState.cs
- BaseTreeIterator.cs
- ImageCodecInfoPrivate.cs
- Aes.cs
- AppearanceEditorPart.cs
- UIElementParagraph.cs
- HttpClientCertificate.cs
- MoveSizeWinEventHandler.cs
- StorageTypeMapping.cs
- OpenFileDialog.cs
- StyleBamlTreeBuilder.cs
- XmlHierarchicalEnumerable.cs
- UniqueConstraint.cs
- ConstNode.cs
- HtmlInputPassword.cs
- TextReader.cs
- Array.cs
- OrderedDictionary.cs
- sqlnorm.cs
- BrushMappingModeValidation.cs
- DataServiceProviderMethods.cs
- PrivilegeNotHeldException.cs
- PlainXmlSerializer.cs
- EditorPartCollection.cs
- ServiceActivationException.cs
- WindowsScroll.cs
- DataGridViewAutoSizeModeEventArgs.cs
- TextEmbeddedObject.cs
- MaxMessageSizeStream.cs
- PenThreadPool.cs
- Debugger.cs
- lengthconverter.cs
- ImmutableDispatchRuntime.cs
- SqlRemoveConstantOrderBy.cs
- Permission.cs
- GridSplitter.cs
- Evaluator.cs
- Token.cs
- AccessDataSourceView.cs
- LicenseException.cs
- DataGridViewDataErrorEventArgs.cs
- ToolBar.cs
- DataKeyCollection.cs
- RetrieveVirtualItemEventArgs.cs
- ExpandSegmentCollection.cs
- WindowsStatic.cs
- RevocationPoint.cs
- SelectorItemAutomationPeer.cs
- SessionStateUtil.cs
- PropertyToken.cs
- MsmqTransportReceiveParameters.cs
- BindingRestrictions.cs
- TemplateControlParser.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- Point3DValueSerializer.cs
- hresults.cs
- CodeMemberProperty.cs
- BeginStoryboard.cs
- DiscoveryMessageSequence.cs
- AppDomainProtocolHandler.cs
- ArgIterator.cs
- _HelperAsyncResults.cs
- IndexedGlyphRun.cs
- validationstate.cs
- VScrollBar.cs
- NavigateEvent.cs
- TabControlCancelEvent.cs
- XmlUnspecifiedAttribute.cs
- BamlReader.cs
- RemoteWebConfigurationHost.cs
- userdatakeys.cs
- BindingOperations.cs
- FaultImportOptions.cs
- ProxyManager.cs
- PropertyTab.cs
- TextTreeInsertUndoUnit.cs
- XmlArrayItemAttributes.cs
- RecommendedAsConfigurableAttribute.cs
- HostingEnvironmentSection.cs
- VerificationException.cs
- serverconfig.cs
- EnumerableRowCollectionExtensions.cs
- RegexMatch.cs
- HtmlInputFile.cs
- SqlDuplicator.cs
- UnSafeCharBuffer.cs
- _WinHttpWebProxyDataBuilder.cs
- ImportCatalogPart.cs
- TreeBuilderBamlTranslator.cs
- TemplateControlParser.cs
- TypeBuilder.cs
- FragmentQueryProcessor.cs
- ItemsPresenter.cs
- diagnosticsswitches.cs
- PagerSettings.cs
- RouteCollection.cs
- ContractComponent.cs
- OperandQuery.cs
- AxisAngleRotation3D.cs
- PropertyBuilder.cs