Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / AuthoringOM / ActivityExecutorDelegateInfo.cs / 1305376 / ActivityExecutorDelegateInfo.cs
namespace System.Workflow.ComponentModel
{
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
public interface IActivityEventListener where T : EventArgs
{
void OnEvent(object sender, T e);
}
[Serializable]
internal sealed class ActivityExecutorDelegateInfo where T : EventArgs
{
private string activityQualifiedName = null;
private IActivityEventListener eventListener = null;
private EventHandler delegateValue = null;
private int contextId = -1;
private bool wantInTransact = false;
private string subscribedActivityQualifiedName = null;
public ActivityExecutorDelegateInfo(EventHandler delegateValue, Activity contextActivity)
: this(false, delegateValue, contextActivity)
{
}
public ActivityExecutorDelegateInfo(IActivityEventListener eventListener, Activity contextActivity)
: this(false, eventListener, contextActivity)
{
}
public ActivityExecutorDelegateInfo(EventHandler delegateValue, Activity contextActivity, bool wantInTransact)
: this(delegateValue, contextActivity)
{
this.wantInTransact = wantInTransact;
}
public ActivityExecutorDelegateInfo(IActivityEventListener eventListener, Activity contextActivity, bool wantInTransact)
: this(eventListener, contextActivity)
{
this.wantInTransact = wantInTransact;
}
internal ActivityExecutorDelegateInfo(bool useCurrentContext, EventHandler delegateValue, Activity contextActivity)
{
this.delegateValue = delegateValue;
Activity target = delegateValue.Target as Activity;
if (contextActivity.WorkflowCoreRuntime != null)
{
if (useCurrentContext)
this.contextId = contextActivity.WorkflowCoreRuntime.CurrentActivity.ContextActivity.ContextId;
else
this.contextId = contextActivity.ContextId;
this.activityQualifiedName = (target ?? contextActivity.WorkflowCoreRuntime.CurrentActivity).QualifiedName;
}
else
{
this.contextId = 1;
this.activityQualifiedName = (target ?? contextActivity.RootActivity).QualifiedName;
}
}
internal ActivityExecutorDelegateInfo(bool useCurrentContext, IActivityEventListener eventListener, Activity contextActivity)
{
this.eventListener = eventListener;
Activity target = eventListener as Activity;
if (contextActivity.WorkflowCoreRuntime != null)
{
if (useCurrentContext)
this.contextId = contextActivity.WorkflowCoreRuntime.CurrentActivity.ContextActivity.ContextId;
else
this.contextId = contextActivity.ContextId;
this.activityQualifiedName = (target ?? contextActivity.WorkflowCoreRuntime.CurrentActivity).QualifiedName;
}
else
{
this.contextId = 1;
this.activityQualifiedName = (target ?? contextActivity.RootActivity).QualifiedName;
}
}
public string ActivityQualifiedName
{
get
{
return this.activityQualifiedName;
}
}
public string SubscribedActivityQualifiedName
{
get
{
return this.subscribedActivityQualifiedName;
}
set
{
this.subscribedActivityQualifiedName = value;
}
}
public int ContextId
{
get
{
return this.contextId;
}
}
public EventHandler HandlerDelegate
{
get
{
return this.delegateValue;
}
}
public IActivityEventListener EventListener
{
get
{
return this.eventListener;
}
}
internal void InvokeDelegate(Activity currentContextActivity, T e, bool [....], bool transacted)
{
Activity targetContextActivity = currentContextActivity.WorkflowCoreRuntime.GetContextActivityForId(this.contextId);
if (targetContextActivity == null)
{
targetContextActivity = FindExecutorForActivityUp(currentContextActivity, this.activityQualifiedName);
if (targetContextActivity == null)
targetContextActivity = FindExecutorForActivityDown(currentContextActivity, this.activityQualifiedName);
}
if (targetContextActivity != null)
InvokeDelegate(currentContextActivity, targetContextActivity, e, [....], transacted);
}
public void InvokeDelegate(Activity currentContextActivity, T e, bool transacted)
{
// If in atomic and subscriber in same scope, or not in atomic scope at all
Activity targetContextActivity = FindExecutorForActivityUp(currentContextActivity, this.activityQualifiedName);
if (targetContextActivity == null)
targetContextActivity = FindExecutorForActivityDown(currentContextActivity, this.activityQualifiedName);
if (targetContextActivity != null)
InvokeDelegate(currentContextActivity, targetContextActivity, e, false, transacted);
}
private void InvokeDelegate(Activity currentContextActivity, Activity targetContextActivity, T e, bool [....], bool transacted)
{
ActivityExecutorDelegateOperation delegateOperation = null;
if(this.delegateValue != null)
delegateOperation = new ActivityExecutorDelegateOperation(this.activityQualifiedName, this.delegateValue, e, this.ContextId);
else
delegateOperation = new ActivityExecutorDelegateOperation(this.activityQualifiedName, this.eventListener, e, this.ContextId);
bool mayInvokeDelegateNow = MayInvokeDelegateNow(currentContextActivity);
if (mayInvokeDelegateNow && [....])
{
Activity targetActivity = targetContextActivity.GetActivityByName(this.activityQualifiedName);
using (currentContextActivity.WorkflowCoreRuntime.SetCurrentActivity(targetActivity))
{
delegateOperation.SynchronousInvoke = true;
delegateOperation.Run(currentContextActivity.WorkflowCoreRuntime);
}
}
else
{
// If in atomic and subscriber not in same scope
// Queue it on the subscriber's baseExecutor
Activity targetActivity = targetContextActivity.GetActivityByName(this.activityQualifiedName);
currentContextActivity.WorkflowCoreRuntime.ScheduleItem(delegateOperation, ActivityExecutionContext.IsInAtomicTransaction(targetActivity), transacted, !mayInvokeDelegateNow);
}
}
private bool MayInvokeDelegateNow(Activity currentContextActivity)
{
// Ok to invoke right away if
// subscriber wants to participate in the current transaction
if ((this.activityQualifiedName == null) || (this.wantInTransact))
return true;
// If not in atomic scope at all,
if (!ActivityExecutionContext.IsInAtomicTransaction(currentContextActivity.WorkflowCoreRuntime.CurrentActivity))
return true;
// Has not started executing yet, queue it up for now
// Not letting it leak out for recv case any more
Activity targetContextActivity = currentContextActivity.WorkflowCoreRuntime.GetContextActivityForId(this.contextId);
if (targetContextActivity == null)
return false;
// or in atomic and subscriber in same scope,
// or in an atomic scope that's not in executing state, e.g. need to fire Scope closed status
Activity targetActivity = targetContextActivity.GetActivityByName(this.activityQualifiedName, true);
if (targetActivity == null)
return false;
if (ActivityExecutionContext.IsInAtomicTransaction(targetActivity) &&
ActivityExecutionContext.IsInAtomicTransaction(currentContextActivity.WorkflowCoreRuntime.CurrentActivity))
return true;
// If the activity receiving the subscription is the scope itself
if (targetActivity.MetaEquals(currentContextActivity))
return true;
return false;
}
private Activity FindExecutorForActivityUp(Activity contextActivity, string activityQualifiedName)
{
while (contextActivity != null)
{
Activity activityToFind = contextActivity.GetActivityByName(activityQualifiedName, true);
if (activityToFind != null && activityToFind.ExecutionStatus != ActivityExecutionStatus.Initialized)
return contextActivity;
contextActivity = contextActivity.ParentContextActivity;
}
return contextActivity;
}
private Activity FindExecutorForActivityDown(Activity contextActivity, string activityQualifiedName)
{
Queue contextActivities = new Queue();
contextActivities.Enqueue(contextActivity);
while (contextActivities.Count > 0)
{
Activity contextActivity2 = contextActivities.Dequeue();
Activity activityToFind = contextActivity2.GetActivityByName(activityQualifiedName, true);
if (activityToFind != null && activityToFind.ExecutionStatus != ActivityExecutionStatus.Initialized)
return contextActivity2;
IList nestedContextActivities = (IList)contextActivity2.GetValue(Activity.ActiveExecutionContextsProperty);
if (nestedContextActivities != null)
{
foreach (Activity nestedContextActivity in nestedContextActivities)
contextActivities.Enqueue(nestedContextActivity);
}
}
return null;
}
public override bool Equals(object obj)
{
ActivityExecutorDelegateInfo otherObject = obj as ActivityExecutorDelegateInfo;
if (otherObject == null)
return false;
return (
(otherObject.delegateValue == null && this.delegateValue == null) ||
(otherObject.delegateValue != null && otherObject.delegateValue.Equals(this.delegateValue))
) &&
(
(otherObject.eventListener == null && this.eventListener == null) ||
(otherObject.eventListener != null && otherObject.eventListener.Equals(this.eventListener))
) &&
otherObject.activityQualifiedName == this.activityQualifiedName &&
otherObject.contextId == this.contextId &&
otherObject.wantInTransact == this.wantInTransact;
}
public override int GetHashCode()
{
return this.delegateValue != null ? this.delegateValue.GetHashCode() : this.eventListener.GetHashCode() ^
this.activityQualifiedName.GetHashCode();
}
[Serializable]
private sealed class ActivityExecutorDelegateOperation : SchedulableItem
{
private string activityQualifiedName = null;
private IActivityEventListener eventListener = null;
private EventHandler delegateValue = null;
private T args = null;
[NonSerialized]
private bool synchronousInvoke = false;
public ActivityExecutorDelegateOperation(string activityQualifiedName, EventHandler delegateValue, T e, int contextId)
: base(contextId, activityQualifiedName)
{
this.activityQualifiedName = activityQualifiedName;
this.delegateValue = delegateValue;
this.args = e;
}
public ActivityExecutorDelegateOperation(string activityQualifiedName, IActivityEventListener eventListener, T e, int contextId)
: base(contextId, activityQualifiedName)
{
this.activityQualifiedName = activityQualifiedName;
this.eventListener = eventListener;
this.args = e;
}
internal bool SynchronousInvoke
{
get
{
return this.synchronousInvoke;
}
set
{
this.synchronousInvoke = value;
}
}
public override bool Run(IWorkflowCoreRuntime workflowCoreRuntime)
{
// get context activity
Activity contextActivity = workflowCoreRuntime.GetContextActivityForId(this.ContextId);
// Work around for ActivityExecutionStatusChangedEventArgs
ActivityExecutionStatusChangedEventArgs activityStatusChangeEventArgs = this.args as ActivityExecutionStatusChangedEventArgs;
if (activityStatusChangeEventArgs != null)
{
activityStatusChangeEventArgs.BaseExecutor = workflowCoreRuntime;
if (activityStatusChangeEventArgs.Activity == null)
{
// status change for an activity that has been deleted dynamically since.
activityStatusChangeEventArgs.BaseExecutor = null;
return false;
}
}
// get activity, if null, or if activity has already closed or just initialized, or if primary has closed and
// the target of the notification is not ActivityExecutionFilter, then
Activity activity = contextActivity.GetActivityByName(this.activityQualifiedName);
if ( activity == null ||
((activity.ExecutionStatus == ActivityExecutionStatus.Closed || activity.ExecutionStatus == ActivityExecutionStatus.Initialized) && !this.synchronousInvoke) ||
(activity.HasPrimaryClosed && !(this.eventListener is ActivityExecutionFilter))
)
return false;
// call the delegate
try
{
using (workflowCoreRuntime.SetCurrentActivity(activity))
{
using (ActivityExecutionContext activityExecutionContext = new ActivityExecutionContext(activity))
{
if (this.delegateValue != null)
this.delegateValue(activityExecutionContext, this.args);
else
this.eventListener.OnEvent(activityExecutionContext, this.args);
}
}
}
catch (Exception e)
{
if (activity != null)
System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 1, "Subscription handler of Activity {0} threw {1}", activity.QualifiedName, e.ToString());
else
System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 1, "Subscription handler threw {0}", e.ToString());
throw;
}
finally
{
// Work around for activity status change Event Args
if (activityStatusChangeEventArgs != null)
activityStatusChangeEventArgs.BaseExecutor = null;
}
return true;
}
public override string ToString()
{
return "SubscriptionEvent(" + "(" + this.ContextId.ToString(CultureInfo.CurrentCulture) + ")" + this.activityQualifiedName + ", " + this.args.ToString() + ")";
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FloatMinMaxAggregationOperator.cs
- ByteStack.cs
- SqlStream.cs
- XmlAnyAttributeAttribute.cs
- Match.cs
- EventNotify.cs
- DelegateBodyWriter.cs
- DSASignatureFormatter.cs
- InfoCardAsymmetricCrypto.cs
- CasesDictionary.cs
- SourceFilter.cs
- SecurityTokenValidationException.cs
- SnapLine.cs
- DayRenderEvent.cs
- MsmqTransportReceiveParameters.cs
- PolyQuadraticBezierSegment.cs
- WindowsClientElement.cs
- QuaternionValueSerializer.cs
- SplitterEvent.cs
- XPathChildIterator.cs
- Point3DAnimation.cs
- GeneralTransformCollection.cs
- IsolationInterop.cs
- WebPartDisplayModeCollection.cs
- PropertyInformationCollection.cs
- ConfigurationLocationCollection.cs
- DataTemplateKey.cs
- linebase.cs
- ClassDataContract.cs
- WindowsListViewGroupSubsetLink.cs
- TextAutomationPeer.cs
- LinkArea.cs
- AutoGeneratedField.cs
- AttachedAnnotation.cs
- BasicViewGenerator.cs
- CrossAppDomainChannel.cs
- ManagementPath.cs
- ApplyHostConfigurationBehavior.cs
- NumberFormatter.cs
- ServiceObjectContainer.cs
- Pipe.cs
- SqlStatistics.cs
- Latin1Encoding.cs
- ConnectionOrientedTransportChannelListener.cs
- XsdDataContractExporter.cs
- ThemeableAttribute.cs
- CompositeDataBoundControl.cs
- followingsibling.cs
- XsltException.cs
- NamespaceEmitter.cs
- ErrorProvider.cs
- XmlUtf8RawTextWriter.cs
- Internal.cs
- SqlDataReaderSmi.cs
- ScrollEvent.cs
- XmlCharCheckingReader.cs
- InertiaRotationBehavior.cs
- AuthenticationModuleElementCollection.cs
- QilLoop.cs
- HttpCacheVaryByContentEncodings.cs
- Native.cs
- HtmlControlPersistable.cs
- XmlSchemaAttributeGroupRef.cs
- NonParentingControl.cs
- WebConfigManager.cs
- TextEncodedRawTextWriter.cs
- MenuCommand.cs
- SubordinateTransaction.cs
- ExpressionBinding.cs
- ClientConfigPaths.cs
- XmlWrappingReader.cs
- UpDownEvent.cs
- XpsFixedDocumentSequenceReaderWriter.cs
- DeferredElementTreeState.cs
- QuaternionIndependentAnimationStorage.cs
- SingleStorage.cs
- WebResponse.cs
- UrlAuthFailedErrorFormatter.cs
- HttpPostedFile.cs
- PasswordPropertyTextAttribute.cs
- FixUp.cs
- FileSystemEnumerable.cs
- PackageStore.cs
- WebPartCloseVerb.cs
- SeverityFilter.cs
- Normalization.cs
- DataControlFieldCollection.cs
- RuleSettings.cs
- HttpCacheVary.cs
- FixedFindEngine.cs
- NetSectionGroup.cs
- FocusManager.cs
- TrackBar.cs
- ConfigXmlText.cs
- SystemException.cs
- RegisteredArrayDeclaration.cs
- EnumerableRowCollection.cs
- EntityDataSourceConfigureObjectContext.cs
- DataGridViewCellValueEventArgs.cs
- ObjectDataSourceMethodEventArgs.cs