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
- WorkItem.cs
- SmiEventSink_DeferedProcessing.cs
- EdmComplexTypeAttribute.cs
- ScriptControl.cs
- DiffuseMaterial.cs
- DiagnosticTrace.cs
- HttpHeaderCollection.cs
- Propagator.Evaluator.cs
- IdentitySection.cs
- OperatorExpressions.cs
- WebPartConnectionsCloseVerb.cs
- RNGCryptoServiceProvider.cs
- Selection.cs
- SettingsPropertyValueCollection.cs
- CultureMapper.cs
- ObjectNotFoundException.cs
- XmlSchemaComplexContent.cs
- IntSecurity.cs
- CompensatableSequenceActivity.cs
- datacache.cs
- ScrollableControl.cs
- InstancePersistenceContext.cs
- ValidationResult.cs
- DataControlLinkButton.cs
- TraceLog.cs
- CatalogPart.cs
- PersonalizableAttribute.cs
- ConfigurationElementProperty.cs
- QueryStringParameter.cs
- Events.cs
- PanelStyle.cs
- PackageStore.cs
- RegionData.cs
- TransformerConfigurationWizardBase.cs
- ConvertTextFrag.cs
- AuthorizationBehavior.cs
- ColorConvertedBitmap.cs
- PassportAuthenticationEventArgs.cs
- BoundField.cs
- ActivationArguments.cs
- ProxyWebPartConnectionCollection.cs
- DetailsViewUpdatedEventArgs.cs
- ContentPropertyAttribute.cs
- UserControl.cs
- prefixendpointaddressmessagefilter.cs
- BamlLocalizableResourceKey.cs
- PropertyGrid.cs
- SemanticBasicElement.cs
- ObjectQueryProvider.cs
- RequiredAttributeAttribute.cs
- ApplicationServiceHelper.cs
- TargetControlTypeCache.cs
- DataTable.cs
- WpfKnownMember.cs
- SevenBitStream.cs
- CheckBoxStandardAdapter.cs
- HelloMessageCD1.cs
- AssemblyAssociatedContentFileAttribute.cs
- BinaryCommonClasses.cs
- ServiceDebugBehavior.cs
- TableLayoutPanelCodeDomSerializer.cs
- ProvidersHelper.cs
- Identity.cs
- ToolZoneDesigner.cs
- ExtendedProperty.cs
- ContentValidator.cs
- IUnknownConstantAttribute.cs
- DesignerDataRelationship.cs
- Keyboard.cs
- shaperfactoryquerycachekey.cs
- ExceptionRoutedEventArgs.cs
- ReachSerializableProperties.cs
- Debug.cs
- DocumentViewerConstants.cs
- MatchNoneMessageFilter.cs
- FixedSchema.cs
- EncryptedKey.cs
- ListViewEditEventArgs.cs
- IncrementalReadDecoders.cs
- SimpleHandlerFactory.cs
- FigureParaClient.cs
- AsyncOperationManager.cs
- TextSelection.cs
- OperationInvokerBehavior.cs
- SymLanguageType.cs
- ConfigurationManagerHelperFactory.cs
- EventLogLink.cs
- CmsUtils.cs
- ConfigXmlWhitespace.cs
- SchemaComplexType.cs
- SoapEnumAttribute.cs
- Propagator.JoinPropagator.cs
- BindingContext.cs
- InputLangChangeRequestEvent.cs
- DBCommandBuilder.cs
- NamedPipeDuplicateContext.cs
- Configuration.cs
- DesignerHelpers.cs
- MetadataCache.cs
- OLEDB_Util.cs