Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / System / Activities / Runtime / BookmarkScopeManager.cs / 1305376 / BookmarkScopeManager.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.Activities.Runtime { using System; using System.Activities.Hosting; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime; using System.Runtime.DurableInstancing; using System.Runtime.Serialization; [DataContract] class BookmarkScopeManager { DictionarybookmarkManagers; List uninitializedScopes; List keysToAssociate; List keysToDisassociate; [DataMember] BookmarkScope defaultScope; [DataMember] long nextTemporaryId; public BookmarkScopeManager() { this.nextTemporaryId = 1; this.defaultScope = CreateAndRegisterScope(Guid.Empty); } public BookmarkScope Default { get { return this.defaultScope; } } public bool HasKeysToUpdate { get { if (this.keysToAssociate != null && this.keysToAssociate.Count > 0) { return true; } if (this.keysToDisassociate != null && this.keysToDisassociate.Count > 0) { return true; } return false; } } [DataMember(EmitDefaultValue = false)] [SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode, Justification = "Called from Serialization")] Dictionary SerializedBookmarkManagers { get { Fx.Assert(this.bookmarkManagers != null && this.bookmarkManagers.Count > 0, "We always have the default sub instance."); return this.bookmarkManagers; } set { Fx.Assert(value != null, "We don't serialize null."); this.bookmarkManagers = value; } } [DataMember(EmitDefaultValue = false)] [SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode, Justification = "Called from Serialization")] List SerializedUninitializedScopes { get { if (this.uninitializedScopes == null || this.uninitializedScopes.Count == 0) { return null; } else { return this.uninitializedScopes; } } set { Fx.Assert(value != null, "We don't serialize null."); this.uninitializedScopes = value; } } long GetNextTemporaryId() { long temp = this.nextTemporaryId; this.nextTemporaryId++; return temp; } public Bookmark CreateBookmark(string name, BookmarkScope scope, BookmarkCallback callback, ActivityInstance owningInstance, BookmarkOptions options) { Fx.Assert(scope != null, "We should never have a null scope."); BookmarkManager manager = null; BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = this.defaultScope; } if (!this.bookmarkManagers.TryGetValue(lookupScope, out manager)) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.RegisteredBookmarkScopeRequired)); } return manager.CreateBookmark(name, callback, owningInstance, options); } public bool RemoveBookmark(Bookmark bookmark, BookmarkScope scope, ActivityInstance instanceAttemptingRemove) { Fx.Assert(scope != null, "We should never have a null scope."); BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = this.defaultScope; } BookmarkManager manager; if (this.bookmarkManagers.TryGetValue(lookupScope, out manager)) { return manager.Remove(bookmark, instanceAttemptingRemove); } else { return false; } } public BookmarkResumptionResult TryGenerateWorkItem(ActivityExecutor executor, ref Bookmark bookmark, BookmarkScope scope, object value, ActivityInstance isolationInstance, bool nonScopedBookmarksExist, out ActivityExecutionWorkItem workItem) { Fx.Assert(scope != null, "We should never have a null sub instance."); BookmarkManager manager = null; workItem = null; BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = this.defaultScope; } // We don't really care about the return value since we'll // use null to know we should check uninitialized sub instances this.bookmarkManagers.TryGetValue(lookupScope, out manager); if (manager == null) { Fx.Assert(lookupScope != null, "The sub instance should not be default if we are here."); BookmarkResumptionResult finalResult = BookmarkResumptionResult.NotFound; // Check the uninitialized sub instances for a matching bookmark if (this.uninitializedScopes != null) { for (int i = 0; i < this.uninitializedScopes.Count; i++) { BookmarkScope uninitializedScope = this.uninitializedScopes[i]; Fx.Assert(this.bookmarkManagers.ContainsKey(uninitializedScope), "We must always have the uninitialized sub instances."); Bookmark internalBookmark; BookmarkCallbackWrapper callbackWrapper; BookmarkResumptionResult resumptionResult; if (!this.bookmarkManagers[uninitializedScope].TryGetBookmarkFromInternalList(bookmark, out internalBookmark, out callbackWrapper)) { resumptionResult = BookmarkResumptionResult.NotFound; } else if (IsExclusiveScopeUnstable(internalBookmark)) { resumptionResult = BookmarkResumptionResult.NotReady; } else { resumptionResult = this.bookmarkManagers[uninitializedScope].TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem); } if (resumptionResult == BookmarkResumptionResult.Success) { // We are using InitializeBookmarkScopeWithoutKeyAssociation because we know this is a new uninitialized scope and // the key we would associate is already associated. And if we did the association here, the subsequent call to // FlushBookmarkScopeKeys would try to flush it out, but it won't have the transaction correct so will hang waiting for // the transaction that has the PersistenceContext locked to complete. But it won't complete successfully until // we finish processing here. InitializeBookmarkScopeWithoutKeyAssociation(uninitializedScope, scope.Id); // We've found what we were looking for return BookmarkResumptionResult.Success; } else if (resumptionResult == BookmarkResumptionResult.NotReady) { // This uninitialized sub-instance has a matching bookmark but // it can't currently be resumed. We won't return BookmarkNotFound // because of this. finalResult = BookmarkResumptionResult.NotReady; } else { if (finalResult == BookmarkResumptionResult.NotFound) { // If we still are planning on returning failure then // we'll incur the cost of seeing if this scope is // stable or not. if (!IsStable(uninitializedScope, nonScopedBookmarksExist)) { // There exists an uninitialized scope which is unstable. // At the very least this means we'll return NotReady since // this uninitialized scope might eventually contain this // bookmark. finalResult = BookmarkResumptionResult.NotReady; } } } } } return finalResult; } else { Bookmark bookmarkFromList; BookmarkCallbackWrapper callbackWrapper; BookmarkResumptionResult resumptionResult; if (!manager.TryGetBookmarkFromInternalList(bookmark, out bookmarkFromList, out callbackWrapper)) { resumptionResult = BookmarkResumptionResult.NotFound; } else { if (IsExclusiveScopeUnstable(bookmarkFromList)) { resumptionResult = BookmarkResumptionResult.NotReady; } else { resumptionResult = manager.TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem); } } if (resumptionResult == BookmarkResumptionResult.NotFound) { if (!IsStable(lookupScope, nonScopedBookmarksExist)) { resumptionResult = BookmarkResumptionResult.NotReady; } } return resumptionResult; } } public void PopulateBookmarkInfo(ref List bookmarks) { foreach (BookmarkManager manager in this.bookmarkManagers.Values) { if (manager.HasBookmarks) { if (bookmarks == null) { bookmarks = new List (); } manager.PopulateBookmarkInfo(bookmarks); } } } public ReadOnlyCollection GetBookmarks(BookmarkScope scope) { Fx.Assert(scope != null, "We should never be passed null here."); BookmarkManager manager = null; BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = this.defaultScope; } if (this.bookmarkManagers.TryGetValue(lookupScope, out manager)) { if (!manager.HasBookmarks) { manager = null; } } if (manager != null) { List bookmarks = new List (); manager.PopulateBookmarkInfo(bookmarks); return new ReadOnlyCollection (bookmarks); } else { return null; } } public ICollection GetKeysToAssociate() { if (this.keysToAssociate == null || this.keysToAssociate.Count == 0) { return null; } ICollection result = this.keysToAssociate; this.keysToAssociate = null; return result; } public ICollection GetKeysToDisassociate() { if (this.keysToDisassociate == null || this.keysToDisassociate.Count == 0) { return null; } ICollection result = this.keysToDisassociate; this.keysToDisassociate = null; return result; } public void InitializeScope(BookmarkScope scope, Guid id) { Fx.Assert(!scope.IsInitialized, "This should have been checked by the caller."); BookmarkScope lookupScope = InitializeBookmarkScopeWithoutKeyAssociation(scope, id); CreateAssociatedKey(lookupScope); } public BookmarkScope InitializeBookmarkScopeWithoutKeyAssociation(BookmarkScope scope, Guid id) { Fx.Assert(!scope.IsInitialized, "This should have been checked by the caller."); BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = this.defaultScope; } if (this.uninitializedScopes == null || !this.uninitializedScopes.Contains(lookupScope)) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarkScopeNotRegisteredForInitialize)); } Fx.Assert(this.bookmarkManagers != null, "This is never null if uninitializedScopes is non-null."); if (this.bookmarkManagers.ContainsKey(new BookmarkScope(id))) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarkScopeWithIdAlreadyExists(id))); } BookmarkManager bookmarks = this.bookmarkManagers[lookupScope]; this.bookmarkManagers.Remove(lookupScope); this.uninitializedScopes.Remove(lookupScope); long temporaryId = lookupScope.TemporaryId; // We initialize and re-add to our dictionary. We have to // re-add because the hash has changed. lookupScope.Id = id; this.bookmarkManagers.Add(lookupScope, bookmarks); if (TD.BookmarkScopeInitializedIsEnabled()) { TD.BookmarkScopeInitialized(temporaryId.ToString(CultureInfo.InvariantCulture), lookupScope.Id.ToString()); } return lookupScope; } public BookmarkScope CreateAndRegisterScope(Guid scopeId) { return this.CreateAndRegisterScope(scopeId, null); } internal BookmarkScope CreateAndRegisterScope(Guid scopeId, BookmarkScopeHandle scopeHandle) { if (this.bookmarkManagers == null) { this.bookmarkManagers = new Dictionary (); } BookmarkScope scope = null; if (scopeId == Guid.Empty) { // // This is the very first activity which started the sub-instance // scope = new BookmarkScope(GetNextTemporaryId()); this.bookmarkManagers.Add(scope, new BookmarkManager(scope, scopeHandle)); if (TD.CreateBookmarkScopeIsEnabled()) { TD.CreateBookmarkScope(ActivityUtilities.GetTraceString(scope)); } if (this.uninitializedScopes == null) { this.uninitializedScopes = new List (); } this.uninitializedScopes.Add(scope); } else { // // Try to find one in the existing sub-instances // foreach (BookmarkScope eachScope in this.bookmarkManagers.Keys) { if (eachScope.Id.Equals(scopeId)) { scope = eachScope; break; } } // // We did not find one, e.g. the first receive will get the correlation id from the // correlation channel // if (scope == null) { scope = new BookmarkScope(scopeId); this.bookmarkManagers.Add(scope, new BookmarkManager(scope, scopeHandle)); if (TD.CreateBookmarkScopeIsEnabled()) { TD.CreateBookmarkScope(string.Format(CultureInfo.InvariantCulture, "Id: {0}", ActivityUtilities.GetTraceString(scope))); } } CreateAssociatedKey(scope); } return scope; } void CreateAssociatedKey(BookmarkScope newScope) { if (this.keysToAssociate == null) { this.keysToAssociate = new List (2); } this.keysToAssociate.Add(new InstanceKey(newScope.Id)); } public void UnregisterScope(BookmarkScope scope) { Fx.Assert(!scope.IsDefault, "Cannot unregister the default sub instance."); if (this.bookmarkManagers == null || !this.bookmarkManagers.ContainsKey(scope)) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarkScopeNotRegisteredForUnregister)); } if (this.bookmarkManagers[scope].HasBookmarks) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarkScopeHasBookmarks)); } this.bookmarkManagers.Remove(scope); if (!scope.IsInitialized) { Fx.Assert(this.uninitializedScopes != null && this.uninitializedScopes.Contains(scope), "Something is wrong with our housekeeping."); this.uninitializedScopes.Remove(scope); } else { if (this.keysToDisassociate == null) { this.keysToDisassociate = new List (2); } this.keysToDisassociate.Add(new InstanceKey(scope.Id)); Fx.Assert(this.uninitializedScopes == null || !this.uninitializedScopes.Contains(scope), "We shouldn't have this in the uninitialized list."); } } bool IsStable(BookmarkScope scope, bool nonScopedBookmarksExist) { Fx.Assert(this.bookmarkManagers.ContainsKey(scope), "The caller should have made sure this scope exists in the bookmark managers dictionary."); if (nonScopedBookmarksExist) { return false; } if (this.bookmarkManagers != null) { foreach (KeyValuePair scopeBookmarks in this.bookmarkManagers) { IEquatable comparison = scopeBookmarks.Key; if (!comparison.Equals(scope)) { if (scopeBookmarks.Value.HasBookmarks) { return false; } } } } return true; } public bool IsExclusiveScopeUnstable(Bookmark bookmark) { if (bookmark.ExclusiveHandles != null) { for (int i = 0; i < bookmark.ExclusiveHandles.Count; i++) { ExclusiveHandle handle = bookmark.ExclusiveHandles[i]; Fx.Assert(handle != null, "Internal error..ExclusiveHandle was null"); if ((handle.ImportantBookmarks != null && handle.ImportantBookmarks.Contains(bookmark)) && (handle.UnimportantBookmarks != null && handle.UnimportantBookmarks.Count != 0)) { return true; } } } return false; } public void PurgeBookmarks(BookmarkManager nonScopedBookmarkManager, Bookmark singleBookmark, IList multipleBookmarks) { if (singleBookmark != null) { PurgeBookmark(singleBookmark, nonScopedBookmarkManager); } else { Fx.Assert(multipleBookmarks != null, "caller should never pass null"); for (int i = 0; i < multipleBookmarks.Count; i++) { Bookmark bookmark = multipleBookmarks[i]; PurgeBookmark(bookmark, nonScopedBookmarkManager); } } } void PurgeBookmark(Bookmark bookmark, BookmarkManager nonScopedBookmarkManager) { BookmarkManager manager = null; if (bookmark.Scope != null) { BookmarkScope lookupScope = bookmark.Scope; if (bookmark.Scope.IsDefault) { lookupScope = this.defaultScope; } Fx.Assert(this.bookmarkManagers.ContainsKey(bookmark.Scope), "We should have the single bookmark's sub instance registered"); manager = this.bookmarkManagers[bookmark.Scope]; } else { manager = nonScopedBookmarkManager; } manager.PurgeSingleBookmark(bookmark); } } } // 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
- ImageSourceValueSerializer.cs
- TextEffect.cs
- SqlMultiplexer.cs
- _HelperAsyncResults.cs
- MemberCollection.cs
- Compiler.cs
- LinqDataSourceView.cs
- XPathExpr.cs
- HijriCalendar.cs
- ObservableCollection.cs
- EventTrigger.cs
- SystemResources.cs
- SQLBinaryStorage.cs
- CheckableControlBaseAdapter.cs
- WebServiceData.cs
- RepeatButton.cs
- ZoomPercentageConverter.cs
- VectorAnimation.cs
- RoutedEventHandlerInfo.cs
- DynamicPropertyReader.cs
- AppSettingsSection.cs
- GuidTagList.cs
- DbSourceCommand.cs
- DesignerToolStripControlHost.cs
- DetailsViewUpdateEventArgs.cs
- ZipIORawDataFileBlock.cs
- PropertySet.cs
- DateBoldEvent.cs
- SectionRecord.cs
- FontStretches.cs
- QueryOptionExpression.cs
- SharedPerformanceCounter.cs
- WebHttpBinding.cs
- DesignTableCollection.cs
- IgnoreSectionHandler.cs
- FormsAuthenticationTicket.cs
- MembershipUser.cs
- FontNameConverter.cs
- InstanceData.cs
- KnownColorTable.cs
- Monitor.cs
- WebServiceReceiveDesigner.cs
- Geometry3D.cs
- ListControlConvertEventArgs.cs
- GuidelineCollection.cs
- GeometryHitTestResult.cs
- HttpRequestWrapper.cs
- PackageDigitalSignature.cs
- AlignmentXValidation.cs
- DocumentPageView.cs
- BaseValidatorDesigner.cs
- NavigationCommands.cs
- securitycriticaldataClass.cs
- EraserBehavior.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- ExplicitDiscriminatorMap.cs
- DataGridViewSelectedColumnCollection.cs
- SecurityTokenException.cs
- DataGridTablesFactory.cs
- SessionViewState.cs
- ObjectDataSource.cs
- FixedTextContainer.cs
- WeakReference.cs
- AssemblyUtil.cs
- ProxyElement.cs
- SqlConnection.cs
- RoutedEventValueSerializer.cs
- DrawingDrawingContext.cs
- Component.cs
- CanExecuteRoutedEventArgs.cs
- Quaternion.cs
- HebrewCalendar.cs
- Debugger.cs
- SemaphoreSecurity.cs
- DictionarySectionHandler.cs
- IndependentAnimationStorage.cs
- _ShellExpression.cs
- XmlSerializationWriter.cs
- DataServiceQuery.cs
- SchemaMapping.cs
- IssuedTokenClientElement.cs
- HttpModuleCollection.cs
- BuildProviderUtils.cs
- SqlConnectionFactory.cs
- HGlobalSafeHandle.cs
- PriorityQueue.cs
- XMLDiffLoader.cs
- ObjectTag.cs
- MessageVersionConverter.cs
- XmlException.cs
- TransformerInfo.cs
- ProcessingInstructionAction.cs
- SqlCacheDependency.cs
- FixedPosition.cs
- DataGridViewImageColumn.cs
- SortedList.cs
- EnumerableRowCollection.cs
- ScaleTransform.cs
- AnnotationObservableCollection.cs
- ItemDragEvent.cs