Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / RunTime / System / Activities / Statements / InteropEnvironment.cs / 1305376 / InteropEnvironment.cs
//---------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------- namespace System.Activities.Statements { using System.Activities; using System.Activities.Tracking; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Reflection; using System.Runtime.Serialization; using System.Transactions; using System.Workflow.Runtime; using System.Workflow.Runtime.Tracking; using System.Runtime; using System.Globalization; class InteropEnvironment : IDisposable, IServiceProvider { static readonly ReadOnlyCollectionemptyList = new ReadOnlyCollection (new IComparable[] { }); static MethodInfo getServiceMethod = typeof(NativeActivityContext).GetMethod("GetExtension"); NativeActivityContext nativeActivityContext; BookmarkCallback bookmarkCallback; bool disposed; bool completed; bool canceled; InteropExecutor executor; IEnumerable initialBookmarks; Exception uncaughtException; Transaction transaction; public InteropEnvironment(InteropExecutor interopExecutor, NativeActivityContext nativeActivityContext, BookmarkCallback bookmarkCallback, Interop activity, Transaction transaction) { //setup environment; this.executor = interopExecutor; this.nativeActivityContext = nativeActivityContext; this.Activity = activity; this.executor.ServiceProvider = this; this.bookmarkCallback = bookmarkCallback; this.transaction = transaction; OnEnter(); } public Interop Activity { get; set; } void IDisposable.Dispose() { if (!this.disposed) { OnExit(); this.disposed = true; } } public void Execute(System.Workflow.ComponentModel.Activity definition, NativeActivityContext context) { Debug.Assert(!disposed, "Cannot access disposed object"); try { this.executor.Initialize(definition, this.Activity.GetInputArgumentValues(context), this.Activity.HasNameCollision); ProcessExecutionStatus(this.executor.Execute()); } catch (Exception e) { this.uncaughtException = e; throw; } } public void Cancel() { Debug.Assert(!disposed, "Cannot access disposed object"); try { ProcessExecutionStatus(this.executor.Cancel()); this.canceled = true; } catch (Exception e) { this.uncaughtException = e; throw; } } public void EnqueueEvent(IComparable queueName, object item) { Debug.Assert(!disposed, "Cannot access disposed object"); try { ProcessExecutionStatus(this.executor.EnqueueEvent(queueName, item)); } catch (Exception e) { this.uncaughtException = e; throw; } } public void TrackActivityStatusChange(System.Workflow.ComponentModel.Activity activity, int eventCounter) { this.nativeActivityContext.Track( new InteropTrackingRecord(this.Activity.DisplayName, new ActivityTrackingRecord( activity.GetType(), activity.QualifiedName, activity.ContextGuid, activity.Parent == null ? Guid.Empty : activity.Parent.ContextGuid, activity.ExecutionStatus, DateTime.UtcNow, eventCounter, null ) ) ); } public void TrackData(System.Workflow.ComponentModel.Activity activity, int eventCounter, string key, object data) { this.nativeActivityContext.Track( new InteropTrackingRecord(this.Activity.DisplayName, new UserTrackingRecord( activity.GetType(), activity.QualifiedName, activity.ContextGuid, activity.Parent == null ? Guid.Empty : activity.Parent.ContextGuid, DateTime.UtcNow, eventCounter, key, data ) ) ); } public void Resume() { Debug.Assert(!disposed, "Cannot access disposed object"); try { ProcessExecutionStatus(this.executor.Resume()); } catch (Exception e) { this.uncaughtException = e; throw; } } // object IServiceProvider.GetService(Type serviceType) { Debug.Assert(!disposed, "Cannot access disposed object"); MethodInfo genericMethodInfo = getServiceMethod.MakeGenericMethod(serviceType); return genericMethodInfo.Invoke(this.nativeActivityContext, null); } public void Persist() { this.Activity.Persist(this.nativeActivityContext); } public void CreateTransaction(TransactionOptions transactionOptions) { this.Activity.CreateTransaction(this.nativeActivityContext, transactionOptions); } public void CommitTransaction() { this.Activity.CommitTransaction(this.nativeActivityContext); } public void AddResourceManager(VolatileResourceManager resourceManager) { this.Activity.AddResourceManager(this.nativeActivityContext,resourceManager); } //Called everytime on enter of interopenvironment. void OnEnter() { //Capture Current state of Queues in InteropEnvironment. this.initialBookmarks = this.executor.Queues; // This method sets up the ambient transaction for the current thread. // Since the runtime can execute us on different threads, // we have to set up the transaction scope everytime we enter the interop environment and clear it when we leave the environment. this.executor.SetAmbientTransactionAndServiceEnvironment(this.transaction); } //Called everytime we leave InteropEnvironment. void OnExit() { if (this.uncaughtException != null) { if (WorkflowExecutor.IsIrrecoverableException(this.uncaughtException)) { return; } } // This method clears the ambient transaction for the current thread. // Since the runtime can execute us on different threads, // we have to set up the transaction scope everytime we enter the interop environment and clear it when we leave the environment. this.executor.ClearAmbientTransactionAndServiceEnvironment(); //Capture Current state of Queues in InteropEnvironment. IEnumerable currentBookmarks = this.executor.Queues; //Set outparameters when completed or faulted. if (this.completed || this.uncaughtException != null) { this.Activity.OnClose(this.nativeActivityContext, this.uncaughtException); this.Activity.SetOutputArgumentValues( this.executor.Outputs, this.nativeActivityContext); this.nativeActivityContext.RemoveAllBookmarks(); this.executor.BookmarkQueueMap.Clear(); if (this.canceled) { this.nativeActivityContext.MarkCanceled(); } } else { //Find Differentials IList deletedBookmarks = new List (); foreach (IComparable value in this.initialBookmarks) { deletedBookmarks.Add(value); } IList newBookmarks = null; foreach (IComparable value in currentBookmarks) { if (!deletedBookmarks.Remove(value)) { if (newBookmarks == null) { newBookmarks = new List (); } newBookmarks.Add(value); } } if (newBookmarks != null) { // Create new Queues as Bookmark. foreach (IComparable bookmark in newBookmarks) { // Bookmark v2Bookmark = this.nativeActivityContext.CreateBookmark(bookmark.ToString(), this.bookmarkCallback, BookmarkOptions.MultipleResume); this.executor.BookmarkQueueMap.Add(v2Bookmark, bookmark); } } // Delete removed queues. foreach (IComparable bookmark in deletedBookmarks) { this.nativeActivityContext.RemoveBookmark(bookmark.ToString()); List bookmarksToRemove = new List (); foreach (KeyValuePair entry in this.executor.BookmarkQueueMap) { if (entry.Value == bookmark) { bookmarksToRemove.Add(entry.Key); } } foreach (Bookmark bookmarkToRemove in bookmarksToRemove) { this.executor.BookmarkQueueMap.Remove(bookmarkToRemove); } } } } void ProcessExecutionStatus(System.Workflow.ComponentModel.ActivityExecutionStatus executionStatus) { this.completed = (executionStatus == System.Workflow.ComponentModel.ActivityExecutionStatus.Closed); } public static class ParameterHelper { static readonly Type activityType = typeof(System.Workflow.ComponentModel.Activity); static readonly Type compositeActivityType = typeof(System.Workflow.ComponentModel.CompositeActivity); static readonly Type dependencyObjectType = typeof(System.Workflow.ComponentModel.DependencyObject); static readonly Type activityConditionType = typeof(System.Workflow.ComponentModel.ActivityCondition); // Interop Property Names internal const string interopPropertyActivityType = "ActivityType"; internal const string interopPropertyActivityProperties = "ActivityProperties"; internal const string interopPropertyActivityMetaProperties = "ActivityMetaProperties"; // Allowed Meta-Properties internal const string activityNameMetaProperty = "Name"; //Check property names for any Property/PropertyOut pairs that would conflict with our naming scheme public static bool HasPropertyNameCollision(IList properties) { bool hasNameCollision = false; HashSet propertyNames = new HashSet (); foreach (PropertyInfo propertyInfo in properties) { propertyNames.Add(propertyInfo.Name); } if (propertyNames.Contains(interopPropertyActivityType) || propertyNames.Contains(interopPropertyActivityProperties) || propertyNames.Contains(interopPropertyActivityMetaProperties)) { hasNameCollision = true; } else { foreach (PropertyInfo propertyInfo in properties) { if (propertyNames.Contains(propertyInfo.Name + Interop.OutArgumentSuffix)) { hasNameCollision = true; break; } } } return hasNameCollision; } public static bool IsBindable(PropertyInfo propertyInfo) { bool isMetaProperty; if (!IsBindableOrMetaProperty(propertyInfo, out isMetaProperty)) { return false; } return !isMetaProperty; } public static bool IsBindableOrMetaProperty(PropertyInfo propertyInfo, out bool isMetaProperty) { isMetaProperty = false; // Validate the declaring type: CompositeActivity and DependencyObject if (propertyInfo.DeclaringType.Equals(compositeActivityType) || propertyInfo.DeclaringType.Equals(dependencyObjectType)) { return false; } // Validate the declaring type: Activity // We allow certain meta-properties on System.Workflow.ComponentModel.Activity to be visible if (propertyInfo.DeclaringType.Equals(activityType) && !String.Equals(propertyInfo.Name, activityNameMetaProperty, StringComparison.Ordinal)) { return false; } //Validate the data type if (activityConditionType.IsAssignableFrom(propertyInfo.PropertyType)) { return false; } //Validate whether there is DP(Meta) backup string dependencyPropertyName = propertyInfo.Name; System.Workflow.ComponentModel.DependencyProperty dependencyProperty = System.Workflow.ComponentModel.DependencyProperty.FromName(dependencyPropertyName, propertyInfo.DeclaringType); if (dependencyProperty != null && dependencyProperty.DefaultMetadata.IsMetaProperty) { isMetaProperty = true; } return true; } } } } // 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
- Vector3DKeyFrameCollection.cs
- StateRuntime.cs
- ButtonField.cs
- ContextMenu.cs
- SoapTypeAttribute.cs
- Int32AnimationBase.cs
- ProcessInputEventArgs.cs
- DataControlFieldCell.cs
- HostedElements.cs
- ReflectionTypeLoadException.cs
- TemplateControl.cs
- ObjectNavigationPropertyMapping.cs
- CounterCreationDataCollection.cs
- PasswordRecovery.cs
- StringUtil.cs
- SqlUnionizer.cs
- RulePatternOps.cs
- KeyInterop.cs
- ObjectConverter.cs
- MultitargetingHelpers.cs
- IdentityModelStringsVersion1.cs
- EnumerableCollectionView.cs
- CachedResourceDictionaryExtension.cs
- CombinedGeometry.cs
- X509CertificateRecipientServiceCredential.cs
- SmtpTransport.cs
- SoapObjectReader.cs
- StringValueSerializer.cs
- DbResourceAllocator.cs
- Bits.cs
- Exceptions.cs
- ScriptingAuthenticationServiceSection.cs
- ProcessModule.cs
- XmlSchemaAttributeGroupRef.cs
- ConnectionPoint.cs
- ObjectSet.cs
- StructuralCache.cs
- ArrayExtension.cs
- CodeGenHelper.cs
- PKCS1MaskGenerationMethod.cs
- CustomErrorsSectionWrapper.cs
- UnionCodeGroup.cs
- ObjectStateManagerMetadata.cs
- ExceptionWrapper.cs
- EmptyWorkItem.cs
- ObjectListDataBindEventArgs.cs
- CompressedStack.cs
- CodeThrowExceptionStatement.cs
- XappLauncher.cs
- Authorization.cs
- MetadataArtifactLoader.cs
- WebPartMenuStyle.cs
- XmlReader.cs
- _ListenerRequestStream.cs
- SqlMethods.cs
- CommonXSendMessage.cs
- TableAdapterManagerNameHandler.cs
- InheritanceContextHelper.cs
- ProxyGenerationError.cs
- AxImporter.cs
- GiveFeedbackEventArgs.cs
- EditorBrowsableAttribute.cs
- BaseServiceProvider.cs
- AsymmetricAlgorithm.cs
- ProfilePropertyMetadata.cs
- CodeIndexerExpression.cs
- SettingsContext.cs
- BeginEvent.cs
- WebPartDescription.cs
- FactoryGenerator.cs
- PropertyStore.cs
- SizeIndependentAnimationStorage.cs
- ServicePointManagerElement.cs
- JoinGraph.cs
- StrokeCollectionDefaultValueFactory.cs
- SerializationAttributes.cs
- ComplusEndpointConfigContainer.cs
- CrossContextChannel.cs
- QueryableDataSourceHelper.cs
- Selector.cs
- CodeSubDirectory.cs
- Action.cs
- XmlQualifiedName.cs
- ListViewEditEventArgs.cs
- PartialClassGenerationTaskInternal.cs
- SmtpReplyReaderFactory.cs
- TypedRowGenerator.cs
- ProxyWebPartConnectionCollection.cs
- WebPartEditorApplyVerb.cs
- IpcClientManager.cs
- Propagator.JoinPropagator.JoinPredicateVisitor.cs
- PersonalizationProviderHelper.cs
- FakeModelItemImpl.cs
- DetailsViewRowCollection.cs
- DefaultValueConverter.cs
- BCryptHashAlgorithm.cs
- PersonalizationProvider.cs
- ControlCachePolicy.cs
- OracleBoolean.cs
- XmlSchemaInfo.cs