Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Threading / LazyInitializer.cs / 1305376 / LazyInitializer.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // LazyInitializer.cs // //[....] // // a set of lightweight static helpers for lazy initialization. // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System.Security.Permissions; using System.Diagnostics.Contracts; namespace System.Threading { ////// Specifies how a public enum LazyThreadSafetyMode { ///instance should synchronize access among multiple threads. /// /// This mode makes no guarantees around the thread-safety of the None, ///instance. If used from multiple threads, the behavior of the is undefined. /// This mode should be used when a is guaranteed to never be initialized from more than one thread simultaneously and high performance is crucial. /// If valueFactory throws an exception when the is initialized, the exception will be cached and returned on subsequent accesses to Value. Also, if valueFactory recursively /// accesses Value on this instance, a will be thrown. /// /// When multiple threads attempt to simultaneously initialize a PublicationOnly, ///instance, this mode allows each thread to execute the /// valueFactory but only the first thread to complete initialization will be allowed to set the final value of the . /// Once initialized successfully, any future calls to Value will return the cached result. If valueFactory throws an exception on any thread, that exception will be /// propagated out of Value. If any thread executes valueFactory without throwing an exception and, therefore, successfully sets the value, that value will be returned on /// subsequent accesses to Value from any thread. If no thread succeeds in setting the value, IsValueCreated will remain false and subsequent accesses to Value will result in /// the valueFactory delegate re-executing. Also, if valueFactory recursively accesses Value on this instance, an exception will NOT be thrown. /// /// This mode uses locks to ensure that only a single thread can initialize a ExecutionAndPublication } ///instance in a thread-safe manner. In general, /// taken if this mode is used in conjunction with a valueFactory delegate that uses locks internally, a deadlock can occur if not /// handled carefully. If valueFactory throws an exception when the is initialized, the exception will be cached and returned on /// subsequent accesses to Value. Also, if valueFactory recursively accesses Value on this instance, a will be thrown. /// /// Provides lazy initialization routines. /// ////// These routines avoid needing to allocate a dedicated, lazy-initialization instance, instead using /// references to ensure targets have been initialized as they are accessed. /// [HostProtection(Synchronization = true, ExternalThreading = true)] public static class LazyInitializer { // The following field is used wherever we need to insert a volatile read. private static volatile object s_barrier = null; ////// Initializes a target reference type with the type's default constructor if the target has not /// already been initialized. /// ///The refence type of the reference to be initialized. /// A reference of typeto initialize if it has not /// already been initialized. /// The initialized reference of type ///. Type ///does not have a default /// constructor. /// Permissions to access the constructor of type ///were missing. /// /// public static T EnsureInitialized/// This method may only be used on reference types. To ensure initialization of value /// types, see other overloads of EnsureInitialized. /// ////// This method may be used concurrently by multiple threads to initialize ///. /// In the event that multiple threads access this method concurrently, multiple instances of /// may be created, but only one will be stored into . In such an occurrence, this method will not dispose of the /// objects that were not stored. If such objects must be disposed, it is up to the caller to determine /// if an object was not used and to then dispose of the object appropriately. /// (ref T target) where T : class { // Fast path. if (target != null) { object barrierGarbage = s_barrier; // Insert a volatile load barrier. Needed on IA64. return target; } return EnsureInitializedCore (ref target, LazyHelpers .s_activatorFactorySelector); } /// /// Initializes a target reference type using the specified function if it has not already been /// initialized. /// ///The reference type of the reference to be initialized. /// The reference of typeto initialize if it has not /// already been initialized. /// The invoked to initialize the /// reference. /// The initialized reference of type ///. Type ///does not have a /// default constructor. /// returned /// null. /// public static T EnsureInitialized/// This method may only be used on reference types, and ///may /// not return a null reference (Nothing in Visual Basic). To ensure initialization of value types or /// to allow null reference types, see other overloads of EnsureInitialized. /// /// This method may be used concurrently by multiple threads to initialize ///. /// In the event that multiple threads access this method concurrently, multiple instances of /// may be created, but only one will be stored into . In such an occurrence, this method will not dispose of the /// objects that were not stored. If such objects must be disposed, it is up to the caller to determine /// if an object was not used and to then dispose of the object appropriately. /// (ref T target, Func valueFactory) where T : class { // Fast path. if (target != null) { object barrierGarbage = s_barrier; // Insert a volatile load barrier. Needed on IA64. return target; } return EnsureInitializedCore (ref target, valueFactory); } /// /// Initialize the target using the given delegate (slow path). /// ///The reference type of the reference to be initialized. /// The variable that need to be initialized /// The delegate that will be executed to initialize the target ///The initialized variable private static T EnsureInitializedCore(ref T target, Func valueFactory) where T : class { T value = valueFactory(); if (value == null) { throw new InvalidOperationException(Environment.GetResourceString("Lazy_StaticInit_InvalidOperation")); } Interlocked.CompareExchange(ref target, value, null); Contract.Assert(target != null); return target; } /// /// Initializes a target reference or value type with its default constructor if it has not already /// been initialized. /// ///The type of the reference to be initialized. /// A reference or value of typeto initialize if it /// has not already been initialized. /// A reference to a boolean that determines whether the target has already /// been initialized. /// A reference to an object used as the mutually exclusive lock for initializing /// . /// The initialized value of type public static T EnsureInitialized. (ref T target, ref bool initialized, ref object syncLock) { // Fast path. if (initialized) { object barrierGarbage = s_barrier; // Insert a volatile load barrier. Needed on IA64. return target; } return EnsureInitializedCore (ref target, ref initialized, ref syncLock, LazyHelpers .s_activatorFactorySelector); } /// /// Initializes a target reference or value type with a specified function if it has not already been /// initialized. /// ///The type of the reference to be initialized. /// A reference or value of typeto initialize if it /// has not already been initialized. /// A reference to a boolean that determines whether the target has already /// been initialized. /// A reference to an object used as the mutually exclusive lock for initializing /// . /// The invoked to initialize the /// reference or value. /// The initialized value of type public static T EnsureInitialized. (ref T target, ref bool initialized, ref object syncLock, Func valueFactory) { // Fast path. if (initialized) { object barrierGarbage = s_barrier; // Insert a volatile load barrier. Needed on IA64. return target; } return EnsureInitializedCore (ref target, ref initialized, ref syncLock, valueFactory); } /// /// Ensure the target is initialized and return the value (slow path). This overload permits nulls /// and also works for value type targets. Uses the supplied function to create the value. /// ///The type of target. /// A reference to the target to be initialized. /// A reference to a location tracking whether the target has been initialized. /// A reference to a location containing a mutual exclusive lock. /// /// Theto invoke in order to produce the lazily-initialized value. /// /// The initialized object. private static T EnsureInitializedCore(ref T target, ref bool initialized, ref object syncLock, Func valueFactory) { // Lazily initialize the lock if necessary. object slock = syncLock; if (slock == null) { object newLock = new object(); slock = Interlocked.CompareExchange(ref syncLock, newLock, null); if (slock == null) { slock = newLock; } } // Now double check that initialization is still required. lock (slock) { if (!initialized) { target = valueFactory(); initialized = true; } } return target; } // Caches the activation selector function to avoid delegate allocations. private static class LazyHelpers { internal static Func s_activatorFactorySelector = new Func (ActivatorFactorySelector); private static T ActivatorFactorySelector() { try { return (T)Activator.CreateInstance(typeof(T)); } catch (MissingMethodException) { throw new MissingMemberException(Environment.GetResourceString("Lazy_CreateValue_NoParameterlessCtorForT")); } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // LazyInitializer.cs // // [....] // // a set of lightweight static helpers for lazy initialization. // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System.Security.Permissions; using System.Diagnostics.Contracts; namespace System.Threading { ////// Specifies how a public enum LazyThreadSafetyMode { ///instance should synchronize access among multiple threads. /// /// This mode makes no guarantees around the thread-safety of the None, ///instance. If used from multiple threads, the behavior of the is undefined. /// This mode should be used when a is guaranteed to never be initialized from more than one thread simultaneously and high performance is crucial. /// If valueFactory throws an exception when the is initialized, the exception will be cached and returned on subsequent accesses to Value. Also, if valueFactory recursively /// accesses Value on this instance, a will be thrown. /// /// When multiple threads attempt to simultaneously initialize a PublicationOnly, ///instance, this mode allows each thread to execute the /// valueFactory but only the first thread to complete initialization will be allowed to set the final value of the . /// Once initialized successfully, any future calls to Value will return the cached result. If valueFactory throws an exception on any thread, that exception will be /// propagated out of Value. If any thread executes valueFactory without throwing an exception and, therefore, successfully sets the value, that value will be returned on /// subsequent accesses to Value from any thread. If no thread succeeds in setting the value, IsValueCreated will remain false and subsequent accesses to Value will result in /// the valueFactory delegate re-executing. Also, if valueFactory recursively accesses Value on this instance, an exception will NOT be thrown. /// /// This mode uses locks to ensure that only a single thread can initialize a ExecutionAndPublication } ///instance in a thread-safe manner. In general, /// taken if this mode is used in conjunction with a valueFactory delegate that uses locks internally, a deadlock can occur if not /// handled carefully. If valueFactory throws an exception when the is initialized, the exception will be cached and returned on /// subsequent accesses to Value. Also, if valueFactory recursively accesses Value on this instance, a will be thrown. /// /// Provides lazy initialization routines. /// ////// These routines avoid needing to allocate a dedicated, lazy-initialization instance, instead using /// references to ensure targets have been initialized as they are accessed. /// [HostProtection(Synchronization = true, ExternalThreading = true)] public static class LazyInitializer { // The following field is used wherever we need to insert a volatile read. private static volatile object s_barrier = null; ////// Initializes a target reference type with the type's default constructor if the target has not /// already been initialized. /// ///The refence type of the reference to be initialized. /// A reference of typeto initialize if it has not /// already been initialized. /// The initialized reference of type ///. Type ///does not have a default /// constructor. /// Permissions to access the constructor of type ///were missing. /// /// public static T EnsureInitialized/// This method may only be used on reference types. To ensure initialization of value /// types, see other overloads of EnsureInitialized. /// ////// This method may be used concurrently by multiple threads to initialize ///. /// In the event that multiple threads access this method concurrently, multiple instances of /// may be created, but only one will be stored into . In such an occurrence, this method will not dispose of the /// objects that were not stored. If such objects must be disposed, it is up to the caller to determine /// if an object was not used and to then dispose of the object appropriately. /// (ref T target) where T : class { // Fast path. if (target != null) { object barrierGarbage = s_barrier; // Insert a volatile load barrier. Needed on IA64. return target; } return EnsureInitializedCore (ref target, LazyHelpers .s_activatorFactorySelector); } /// /// Initializes a target reference type using the specified function if it has not already been /// initialized. /// ///The reference type of the reference to be initialized. /// The reference of typeto initialize if it has not /// already been initialized. /// The invoked to initialize the /// reference. /// The initialized reference of type ///. Type ///does not have a /// default constructor. /// returned /// null. /// public static T EnsureInitialized/// This method may only be used on reference types, and ///may /// not return a null reference (Nothing in Visual Basic). To ensure initialization of value types or /// to allow null reference types, see other overloads of EnsureInitialized. /// /// This method may be used concurrently by multiple threads to initialize ///. /// In the event that multiple threads access this method concurrently, multiple instances of /// may be created, but only one will be stored into . In such an occurrence, this method will not dispose of the /// objects that were not stored. If such objects must be disposed, it is up to the caller to determine /// if an object was not used and to then dispose of the object appropriately. /// (ref T target, Func valueFactory) where T : class { // Fast path. if (target != null) { object barrierGarbage = s_barrier; // Insert a volatile load barrier. Needed on IA64. return target; } return EnsureInitializedCore (ref target, valueFactory); } /// /// Initialize the target using the given delegate (slow path). /// ///The reference type of the reference to be initialized. /// The variable that need to be initialized /// The delegate that will be executed to initialize the target ///The initialized variable private static T EnsureInitializedCore(ref T target, Func valueFactory) where T : class { T value = valueFactory(); if (value == null) { throw new InvalidOperationException(Environment.GetResourceString("Lazy_StaticInit_InvalidOperation")); } Interlocked.CompareExchange(ref target, value, null); Contract.Assert(target != null); return target; } /// /// Initializes a target reference or value type with its default constructor if it has not already /// been initialized. /// ///The type of the reference to be initialized. /// A reference or value of typeto initialize if it /// has not already been initialized. /// A reference to a boolean that determines whether the target has already /// been initialized. /// A reference to an object used as the mutually exclusive lock for initializing /// . /// The initialized value of type public static T EnsureInitialized. (ref T target, ref bool initialized, ref object syncLock) { // Fast path. if (initialized) { object barrierGarbage = s_barrier; // Insert a volatile load barrier. Needed on IA64. return target; } return EnsureInitializedCore (ref target, ref initialized, ref syncLock, LazyHelpers .s_activatorFactorySelector); } /// /// Initializes a target reference or value type with a specified function if it has not already been /// initialized. /// ///The type of the reference to be initialized. /// A reference or value of typeto initialize if it /// has not already been initialized. /// A reference to a boolean that determines whether the target has already /// been initialized. /// A reference to an object used as the mutually exclusive lock for initializing /// . /// The invoked to initialize the /// reference or value. /// The initialized value of type public static T EnsureInitialized. (ref T target, ref bool initialized, ref object syncLock, Func valueFactory) { // Fast path. if (initialized) { object barrierGarbage = s_barrier; // Insert a volatile load barrier. Needed on IA64. return target; } return EnsureInitializedCore (ref target, ref initialized, ref syncLock, valueFactory); } /// /// Ensure the target is initialized and return the value (slow path). This overload permits nulls /// and also works for value type targets. Uses the supplied function to create the value. /// ///The type of target. /// A reference to the target to be initialized. /// A reference to a location tracking whether the target has been initialized. /// A reference to a location containing a mutual exclusive lock. /// /// Theto invoke in order to produce the lazily-initialized value. /// /// The initialized object. private static T EnsureInitializedCore(ref T target, ref bool initialized, ref object syncLock, Func valueFactory) { // Lazily initialize the lock if necessary. object slock = syncLock; if (slock == null) { object newLock = new object(); slock = Interlocked.CompareExchange(ref syncLock, newLock, null); if (slock == null) { slock = newLock; } } // Now double check that initialization is still required. lock (slock) { if (!initialized) { target = valueFactory(); initialized = true; } } return target; } // Caches the activation selector function to avoid delegate allocations. private static class LazyHelpers { internal static Func s_activatorFactorySelector = new Func (ActivatorFactorySelector); private static T ActivatorFactorySelector() { try { return (T)Activator.CreateInstance(typeof(T)); } catch (MissingMethodException) { throw new MissingMemberException(Environment.GetResourceString("Lazy_CreateValue_NoParameterlessCtorForT")); } } } } } // 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
- WebUtil.cs
- XmlSchemaSubstitutionGroup.cs
- controlskin.cs
- DelimitedListTraceListener.cs
- DBProviderConfigurationHandler.cs
- IRCollection.cs
- SecurityAppliedMessage.cs
- EasingQuaternionKeyFrame.cs
- Activity.cs
- DtdParser.cs
- RoutingTable.cs
- DataFieldConverter.cs
- LineBreakRecord.cs
- IndicCharClassifier.cs
- XmlSchemaAnnotation.cs
- Message.cs
- XmlMembersMapping.cs
- ScheduleChanges.cs
- EncodingInfo.cs
- UnionCqlBlock.cs
- WebPartConnectionsDisconnectVerb.cs
- XmlNamespaceMappingCollection.cs
- ValidationRuleCollection.cs
- HitTestFilterBehavior.cs
- XMLUtil.cs
- WizardPanel.cs
- Pair.cs
- ResourceDefaultValueAttribute.cs
- ClientConfigPaths.cs
- Mappings.cs
- DecoderFallback.cs
- NotImplementedException.cs
- ControlAdapter.cs
- EnumMemberAttribute.cs
- KeyTime.cs
- SpeechUI.cs
- Wizard.cs
- PtsHelper.cs
- _CommandStream.cs
- _NegoState.cs
- AtomPub10CategoriesDocumentFormatter.cs
- ScrollEventArgs.cs
- SingleStorage.cs
- CompiledXpathExpr.cs
- TextParagraph.cs
- NativeObjectSecurity.cs
- CommandDesigner.cs
- safesecurityhelperavalon.cs
- BuilderInfo.cs
- SyndicationSerializer.cs
- ServiceModelPerformanceCounters.cs
- ConfigWriter.cs
- TdsEnums.cs
- IndividualDeviceConfig.cs
- DeferredTextReference.cs
- MetadataHelper.cs
- NameNode.cs
- RSACryptoServiceProvider.cs
- WebPartMovingEventArgs.cs
- DataGridViewCellMouseEventArgs.cs
- EditorAttribute.cs
- MetadataWorkspace.cs
- EdmComplexPropertyAttribute.cs
- BitmapEffectInput.cs
- DllNotFoundException.cs
- InternalRelationshipCollection.cs
- Workspace.cs
- ScriptManagerProxy.cs
- MemoryStream.cs
- Walker.cs
- PropertyAccessVisitor.cs
- ContextMenuService.cs
- MissingManifestResourceException.cs
- XmlSchemaAttributeGroup.cs
- ModelFunctionTypeElement.cs
- ExpressionParser.cs
- ISFClipboardData.cs
- DelegateSerializationHolder.cs
- DataGridViewElement.cs
- LayoutTableCell.cs
- RequiredFieldValidator.cs
- WebException.cs
- Maps.cs
- ItemContainerGenerator.cs
- PageAsyncTaskManager.cs
- ObjectToIdCache.cs
- DesignerOptions.cs
- TextEndOfSegment.cs
- DataGridViewDataErrorEventArgs.cs
- SqlCacheDependencySection.cs
- activationcontext.cs
- DoubleUtil.cs
- BinaryWriter.cs
- Mappings.cs
- AttributeData.cs
- TextTreeRootTextBlock.cs
- ObjectMemberMapping.cs
- FontFamilyValueSerializer.cs
- DataGridViewComponentPropertyGridSite.cs
- DebugView.cs