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 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
- ReferenceService.cs
- BridgeDataRecord.cs
- SafeNativeMethods.cs
- SafeIUnknown.cs
- WebPartUtil.cs
- DbReferenceCollection.cs
- HiddenField.cs
- TextPattern.cs
- PrivilegeNotHeldException.cs
- ListBoxAutomationPeer.cs
- PrefixHandle.cs
- RadioButtonBaseAdapter.cs
- ProgressBarHighlightConverter.cs
- RequiredArgumentAttribute.cs
- ExecutionScope.cs
- SortDescription.cs
- NativeCompoundFileAPIs.cs
- ConfigXmlReader.cs
- ResourceSet.cs
- SqlProcedureAttribute.cs
- columnmapfactory.cs
- RelativeSource.cs
- ChannelParameterCollection.cs
- RTLAwareMessageBox.cs
- EncoderNLS.cs
- DataGridItemAutomationPeer.cs
- QuotedPrintableStream.cs
- LocalizationParserHooks.cs
- QuaternionAnimationUsingKeyFrames.cs
- DataGridViewTextBoxEditingControl.cs
- XamlReaderHelper.cs
- ToolStripSeparatorRenderEventArgs.cs
- BindingFormattingDialog.cs
- DataGridViewRowPostPaintEventArgs.cs
- TreeNodeSelectionProcessor.cs
- CapabilitiesUse.cs
- BooleanToSelectiveScrollingOrientationConverter.cs
- ProcessHost.cs
- TemplateEditingService.cs
- AsymmetricKeyExchangeDeformatter.cs
- GridView.cs
- AssociatedControlConverter.cs
- XmlObjectSerializer.cs
- GenerateTemporaryAssemblyTask.cs
- XmlParser.cs
- VBCodeProvider.cs
- OperatingSystemVersionCheck.cs
- PageThemeParser.cs
- VectorCollectionConverter.cs
- SafeArrayRankMismatchException.cs
- WebPartConnectionCollection.cs
- InvalidComObjectException.cs
- ContainerActivationHelper.cs
- HotSpotCollection.cs
- ManipulationStartedEventArgs.cs
- FlowPosition.cs
- StyleCollection.cs
- DataGridViewCellToolTipTextNeededEventArgs.cs
- IDQuery.cs
- CategoryGridEntry.cs
- BufferedStream.cs
- DispatcherHooks.cs
- FromReply.cs
- DataGridViewColumn.cs
- BitHelper.cs
- DbConnectionPoolGroupProviderInfo.cs
- SqlProvider.cs
- ConfigurationSectionGroupCollection.cs
- XmlNodeComparer.cs
- ServiceObjectContainer.cs
- Compress.cs
- TransformValueSerializer.cs
- OuterGlowBitmapEffect.cs
- Renderer.cs
- ChangeBlockUndoRecord.cs
- Parallel.cs
- Point3D.cs
- UDPClient.cs
- ExpressionHelper.cs
- TreeWalkHelper.cs
- PageThemeParser.cs
- QueryParameter.cs
- ShapeTypeface.cs
- DesignColumn.cs
- ListViewGroupConverter.cs
- DictionaryBase.cs
- WebReferenceOptions.cs
- HandledEventArgs.cs
- SqlDataRecord.cs
- DesignerInterfaces.cs
- odbcmetadatacollectionnames.cs
- UTF7Encoding.cs
- XmlSerializationGeneratedCode.cs
- NodeFunctions.cs
- FlowDocumentScrollViewerAutomationPeer.cs
- ScriptControl.cs
- PersonalizationEntry.cs
- UserNameSecurityTokenAuthenticator.cs
- SqlClientWrapperSmiStreamChars.cs
- Int32Rect.cs