Code:
/ 4.0 / 4.0 / 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. //---------------------------------------------------------------- // 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 ReadOnlyCollection emptyList = 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
- DispatcherHooks.cs
- DataGridViewTextBoxCell.cs
- CalendarTable.cs
- DependencySource.cs
- DbParameterCollection.cs
- DBDataPermissionAttribute.cs
- OleServicesContext.cs
- FacetValueContainer.cs
- JsonStringDataContract.cs
- UInt32Converter.cs
- RadioButtonAutomationPeer.cs
- ConfigXmlText.cs
- NetworkStream.cs
- ClickablePoint.cs
- ScriptHandlerFactory.cs
- XmlValidatingReader.cs
- WeakEventManager.cs
- FragmentNavigationEventArgs.cs
- PassportAuthentication.cs
- XPathScanner.cs
- ItemsPanelTemplate.cs
- GregorianCalendarHelper.cs
- ActivationServices.cs
- StylusShape.cs
- PtsHost.cs
- SystemResources.cs
- bidPrivateBase.cs
- DataBoundControl.cs
- SecurityTokenSpecification.cs
- ControlUtil.cs
- MeshGeometry3D.cs
- HwndMouseInputProvider.cs
- EventBuilder.cs
- versioninfo.cs
- FileDialog_Vista.cs
- MenuEventArgs.cs
- ExtendedProperty.cs
- UpdateTranslator.cs
- SemaphoreSecurity.cs
- SelectionItemPattern.cs
- SystemUdpStatistics.cs
- ControlBuilderAttribute.cs
- PathFigureCollection.cs
- LogEntry.cs
- NumberFormatter.cs
- CompilerErrorCollection.cs
- CustomAttributeSerializer.cs
- IDataContractSurrogate.cs
- TextParaLineResult.cs
- ByteStorage.cs
- PlatformCulture.cs
- URIFormatException.cs
- AttributeUsageAttribute.cs
- ToolZone.cs
- UrlMappingsSection.cs
- ObjectAssociationEndMapping.cs
- Application.cs
- SamlDelegatingWriter.cs
- XmlNamespaceManager.cs
- ObjectViewListener.cs
- RightsManagementProvider.cs
- VideoDrawing.cs
- C14NUtil.cs
- RawStylusActions.cs
- RectConverter.cs
- UseManagedPresentationBindingElementImporter.cs
- AttributeXamlType.cs
- X509SecurityToken.cs
- RuntimeComponentFilter.cs
- BinHexEncoder.cs
- CallSite.cs
- DataRecordInternal.cs
- SqlProviderManifest.cs
- OrthographicCamera.cs
- PropertyGridCommands.cs
- HyperLink.cs
- HtmlEncodedRawTextWriter.cs
- LinearQuaternionKeyFrame.cs
- DirtyTextRange.cs
- SwitchDesigner.xaml.cs
- HttpApplication.cs
- PolyBezierSegment.cs
- Int16Animation.cs
- ColorBlend.cs
- MessageBox.cs
- DirectoryObjectSecurity.cs
- AnnotationAdorner.cs
- WCFServiceClientProxyGenerator.cs
- FixedSOMTableRow.cs
- MSG.cs
- OleDbParameter.cs
- DataGridTable.cs
- NetNamedPipeBinding.cs
- CompositeScriptReference.cs
- PaintValueEventArgs.cs
- GregorianCalendar.cs
- SByteStorage.cs
- AmbiguousMatchException.cs
- DefaultAutoFieldGenerator.cs
- EventSourceCreationData.cs