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
- CodeSnippetExpression.cs
- MenuItemBinding.cs
- Transform.cs
- ConfigurationSettings.cs
- EntityModelBuildProvider.cs
- WinEventQueueItem.cs
- LayoutTableCell.cs
- TrueReadOnlyCollection.cs
- DockPattern.cs
- WebPartMenuStyle.cs
- _UncName.cs
- MemberHolder.cs
- PermissionAttributes.cs
- UnitySerializationHolder.cs
- PrivilegeNotHeldException.cs
- DbProviderServices.cs
- DataListItemEventArgs.cs
- BitmapEditor.cs
- SmiEventSink_DeferedProcessing.cs
- SmtpTransport.cs
- OdbcPermission.cs
- XPathNode.cs
- PasswordRecovery.cs
- AppDomain.cs
- FileCodeGroup.cs
- MetadataPropertyCollection.cs
- XmlSchemaType.cs
- SequentialOutput.cs
- ContentPlaceHolderDesigner.cs
- MsmqInputMessage.cs
- Journal.cs
- AdornedElementPlaceholder.cs
- DataPagerFieldCommandEventArgs.cs
- HandleExceptionArgs.cs
- Rule.cs
- Marshal.cs
- Int32CAMarshaler.cs
- EntityDesignerDataSourceView.cs
- OdbcEnvironmentHandle.cs
- StructuredTypeEmitter.cs
- ExpressionNormalizer.cs
- UriScheme.cs
- Win32MouseDevice.cs
- InitializingNewItemEventArgs.cs
- BridgeDataRecord.cs
- StreamedWorkflowDefinitionContext.cs
- DefaultObjectMappingItemCollection.cs
- XmlCodeExporter.cs
- ParameterExpression.cs
- CaseExpr.cs
- _LocalDataStore.cs
- SqlMultiplexer.cs
- CustomExpression.cs
- _FtpDataStream.cs
- DataRow.cs
- ErrorRuntimeConfig.cs
- FileAuthorizationModule.cs
- EdmSchemaError.cs
- DemultiplexingClientMessageFormatter.cs
- Calendar.cs
- ResourcePermissionBase.cs
- AuditLogLocation.cs
- Stream.cs
- Pts.cs
- TraceSource.cs
- BamlWriter.cs
- TableCellAutomationPeer.cs
- TrackingValidationObjectDictionary.cs
- ParameterToken.cs
- LayoutExceptionEventArgs.cs
- SettingsPropertyIsReadOnlyException.cs
- CompositeControl.cs
- CodeEntryPointMethod.cs
- IRCollection.cs
- RoutedEvent.cs
- IImplicitResourceProvider.cs
- ToolStripDropDownClosingEventArgs.cs
- TextMetrics.cs
- DesignerListAdapter.cs
- WindowsEditBox.cs
- StringHelper.cs
- AspCompat.cs
- InputManager.cs
- PreservationFileReader.cs
- CodeTypeConstructor.cs
- InternalConfirm.cs
- BaseCAMarshaler.cs
- CompositeTypefaceMetrics.cs
- HandlerWithFactory.cs
- GestureRecognizer.cs
- MasterPageCodeDomTreeGenerator.cs
- RequestSecurityToken.cs
- UMPAttributes.cs
- DelegatingConfigHost.cs
- TrackingServices.cs
- WebPartConnectionsCancelEventArgs.cs
- Barrier.cs
- FileDetails.cs
- _SafeNetHandles.cs
- XmlLanguageConverter.cs