Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FieldTemplateUserControl.cs
- MediaCommands.cs
- GenericWebPart.cs
- ImageBrush.cs
- ProxyHelper.cs
- TextTreeTextNode.cs
- XmlNamespaceMapping.cs
- NamespaceInfo.cs
- WebPartExportVerb.cs
- Annotation.cs
- RelationshipDetailsRow.cs
- DataGridViewHitTestInfo.cs
- UnsafeNativeMethods.cs
- IntegrationExceptionEventArgs.cs
- PointAnimationUsingKeyFrames.cs
- OracleParameter.cs
- Parser.cs
- AnnotationStore.cs
- PermissionToken.cs
- AvTraceFormat.cs
- ModelProperty.cs
- SqlXmlStorage.cs
- ConfigurationLocationCollection.cs
- XPathScanner.cs
- TemplateBaseAction.cs
- ObjectView.cs
- CompositeControl.cs
- ComAdminWrapper.cs
- TextEditorCharacters.cs
- DataGridPageChangedEventArgs.cs
- ExpressionBuilder.cs
- XmlValidatingReaderImpl.cs
- DataGridViewCellStyleConverter.cs
- RowsCopiedEventArgs.cs
- DataGridViewDesigner.cs
- QuaternionValueSerializer.cs
- Light.cs
- AccessibleObject.cs
- TemplateField.cs
- Evaluator.cs
- StyleSheetComponentEditor.cs
- PeerInvitationResponse.cs
- WebPartUserCapability.cs
- OleDbRowUpdatedEvent.cs
- DbProviderFactory.cs
- SrgsRuleRef.cs
- GroupDescription.cs
- HttpCachePolicyElement.cs
- AssemblyFilter.cs
- EdmConstants.cs
- NativeObjectSecurity.cs
- URL.cs
- XmlExtensionFunction.cs
- AutomationElement.cs
- LayoutManager.cs
- BindingValueChangedEventArgs.cs
- AppSettingsSection.cs
- CodeLabeledStatement.cs
- ITextView.cs
- ExpressionConverter.cs
- UnitySerializationHolder.cs
- HandlerMappingMemo.cs
- DataGridViewCellEventArgs.cs
- DataRecordInternal.cs
- ImageSourceConverter.cs
- COM2ICategorizePropertiesHandler.cs
- ListViewGroupConverter.cs
- StorageAssociationTypeMapping.cs
- DataRelation.cs
- TrackingLocation.cs
- PersistenceException.cs
- ServiceHttpHandlerFactory.cs
- DataGridViewLayoutData.cs
- RegexFCD.cs
- RTTrackingProfile.cs
- Variable.cs
- MessageSmuggler.cs
- CompositeCollectionView.cs
- SystemIPInterfaceStatistics.cs
- DrawingGroup.cs
- DesignerExtenders.cs
- LeaseManager.cs
- ToolboxDataAttribute.cs
- WebPartConnectionsConfigureVerb.cs
- Utils.cs
- OdbcDataAdapter.cs
- BinaryObjectInfo.cs
- SoapMessage.cs
- AudioBase.cs
- Schema.cs
- UIElement3D.cs
- assemblycache.cs
- TagMapInfo.cs
- DebuggerAttributes.cs
- EDesignUtil.cs
- HttpCachePolicyWrapper.cs
- KeyValueConfigurationElement.cs
- SoapAttributeOverrides.cs
- ActivityCodeDomSerializationManager.cs
- LinqDataSourceValidationException.cs