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
- Stack.cs
- Formatter.cs
- XmlSchemaExporter.cs
- ResourceAttributes.cs
- SqlClientWrapperSmiStream.cs
- CmsUtils.cs
- DateTimeConverter2.cs
- VideoDrawing.cs
- NumberFormatter.cs
- TypeConverterHelper.cs
- CryptoSession.cs
- ForeignKeyConstraint.cs
- UrlPropertyAttribute.cs
- DefaultMemberAttribute.cs
- FilterQuery.cs
- DesignerCatalogPartChrome.cs
- FlowDocumentPage.cs
- PropertyGrid.cs
- SqlConnectionPoolProviderInfo.cs
- MonitorWrapper.cs
- AuthorizationPolicyTypeElementCollection.cs
- PointHitTestParameters.cs
- ExtenderProvidedPropertyAttribute.cs
- ConfigurationStrings.cs
- NetworkStream.cs
- Int32CollectionValueSerializer.cs
- DefaultValueTypeConverter.cs
- MaterializeFromAtom.cs
- InstanceOwnerQueryResult.cs
- RelatedView.cs
- StorageBasedPackageProperties.cs
- ListItemDetailViewAttribute.cs
- WebPartCatalogAddVerb.cs
- SqlVersion.cs
- CardSpacePolicyElement.cs
- HttpListenerTimeoutManager.cs
- XmlSchemaComplexContent.cs
- UriTemplateVariablePathSegment.cs
- RangeEnumerable.cs
- CodeDOMProvider.cs
- DesignerValidatorAdapter.cs
- XmlLinkedNode.cs
- PrintDialog.cs
- HopperCache.cs
- XamlDesignerSerializationManager.cs
- coordinator.cs
- WebZoneDesigner.cs
- SharedStatics.cs
- WebPartManager.cs
- InvalidPrinterException.cs
- ExceptionUtility.cs
- InstanceDataCollectionCollection.cs
- XmlCharType.cs
- LoadMessageLogger.cs
- DataGridPagerStyle.cs
- DataSourceDescriptorCollection.cs
- PackUriHelper.cs
- WebFormDesignerActionService.cs
- UnsafeNativeMethods.cs
- DataGridRow.cs
- CollectionAdapters.cs
- PermissionRequestEvidence.cs
- SiteMapDataSourceView.cs
- ServiceOperationInfoTypeConverter.cs
- HotSpotCollection.cs
- HtmlWindow.cs
- COM2Enum.cs
- GeneralTransform.cs
- SystemParameters.cs
- SystemKeyConverter.cs
- XmlSchemaSubstitutionGroup.cs
- CollectionViewProxy.cs
- WebResourceUtil.cs
- HeaderedItemsControl.cs
- TypeDescriptionProviderAttribute.cs
- WmlLiteralTextAdapter.cs
- NativeCppClassAttribute.cs
- PackageFilter.cs
- DummyDataSource.cs
- SimpleBitVector32.cs
- HebrewNumber.cs
- StateManager.cs
- ErrorWrapper.cs
- ExpandedWrapper.cs
- TextTreeRootNode.cs
- CorePropertiesFilter.cs
- ApplicationDirectory.cs
- ObjectQuery_EntitySqlExtensions.cs
- PageVisual.cs
- TrailingSpaceComparer.cs
- GeneratedCodeAttribute.cs
- MissingFieldException.cs
- WebPartConnectionsCloseVerb.cs
- odbcmetadatacollectionnames.cs
- ComplexBindingPropertiesAttribute.cs
- XmlDictionaryReader.cs
- DesignerCommandAdapter.cs
- DESCryptoServiceProvider.cs
- DesignerMetadata.cs
- RIPEMD160.cs