You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,159 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime;
|
||||
using System.Globalization;
|
||||
|
||||
[Fx.Tag.XamlVisible(false)]
|
||||
[DataContract]
|
||||
public sealed class ActivityInfo
|
||||
{
|
||||
string name;
|
||||
string id;
|
||||
string instanceId;
|
||||
long instanceIdInternal;
|
||||
string typeName;
|
||||
|
||||
public ActivityInfo(string name, string id, string instanceId, string typeName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNullOrEmpty("name");
|
||||
}
|
||||
if (string.IsNullOrEmpty(id))
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNullOrEmpty("id");
|
||||
}
|
||||
if (string.IsNullOrEmpty(instanceId))
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNullOrEmpty("instanceId");
|
||||
}
|
||||
if (string.IsNullOrEmpty(typeName))
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNullOrEmpty("typeName");
|
||||
}
|
||||
this.Name = name;
|
||||
this.Id = id;
|
||||
this.InstanceId = instanceId;
|
||||
this.TypeName = typeName;
|
||||
}
|
||||
|
||||
internal ActivityInfo(ActivityInstance instance)
|
||||
: this(instance.Activity, instance.InternalId)
|
||||
{
|
||||
this.Instance = instance;
|
||||
}
|
||||
|
||||
internal ActivityInfo(Activity activity, long instanceId)
|
||||
{
|
||||
this.Activity = activity;
|
||||
this.instanceIdInternal = instanceId;
|
||||
}
|
||||
|
||||
internal ActivityInstance Instance
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.name))
|
||||
{
|
||||
Fx.Assert(this.Activity != null, "Activity not set");
|
||||
this.name = this.Activity.DisplayName;
|
||||
}
|
||||
return this.name;
|
||||
}
|
||||
// Internal visibility for partial trust serialization purposes only.
|
||||
internal set
|
||||
{
|
||||
Fx.Assert(!string.IsNullOrEmpty(value), "Name cannot be null or empty");
|
||||
this.name = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string Id
|
||||
{
|
||||
get
|
||||
{
|
||||
if (String.IsNullOrEmpty(this.id))
|
||||
{
|
||||
Fx.Assert(this.Activity != null, "Activity not set");
|
||||
this.id = this.Activity.Id;
|
||||
}
|
||||
return this.id;
|
||||
}
|
||||
// Internal visibility for partial trust serialization purposes only.
|
||||
internal set
|
||||
{
|
||||
Fx.Assert(!string.IsNullOrEmpty(value), "Id cannot be null or empty");
|
||||
this.id = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string InstanceId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.instanceId))
|
||||
{
|
||||
this.instanceId = this.instanceIdInternal.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
return this.instanceId;
|
||||
}
|
||||
// Internal visibility for partial trust serialization purposes only.
|
||||
internal set
|
||||
{
|
||||
Fx.Assert(!string.IsNullOrEmpty(value), "InstanceId cannot be null or empty");
|
||||
this.instanceId = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string TypeName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.typeName))
|
||||
{
|
||||
Fx.Assert(this.Activity != null, "Activity not set");
|
||||
this.typeName = this.Activity.GetType().FullName;
|
||||
}
|
||||
return this.typeName;
|
||||
}
|
||||
// Internal visibility for partial trust serialization purposes only.
|
||||
internal set
|
||||
{
|
||||
Fx.Assert(!string.IsNullOrEmpty(value), "TypeName cannot be null or empty");
|
||||
this.typeName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture,
|
||||
"Name={0}, ActivityId = {1}, ActivityInstanceId = {2}, TypeName={3}",
|
||||
this.Name,
|
||||
this.Id,
|
||||
this.InstanceId,
|
||||
this.TypeName);
|
||||
}
|
||||
|
||||
internal Activity Activity
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
public sealed class ActivityScheduledQuery : TrackingQuery
|
||||
{
|
||||
public ActivityScheduledQuery()
|
||||
{
|
||||
this.ActivityName = "*";
|
||||
this.ChildActivityName = "*";
|
||||
}
|
||||
|
||||
public string ActivityName { get; set; }
|
||||
public string ChildActivityName { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime;
|
||||
using System.Globalization;
|
||||
|
||||
[Fx.Tag.XamlVisible(false)]
|
||||
[DataContract]
|
||||
public sealed class ActivityScheduledRecord : TrackingRecord
|
||||
{
|
||||
ActivityInfo activity;
|
||||
ActivityInfo child;
|
||||
|
||||
internal ActivityScheduledRecord(Guid instanceId, ActivityInstance instance, ActivityInstance child)
|
||||
: this(instanceId, instance, new ActivityInfo(child))
|
||||
{
|
||||
}
|
||||
|
||||
internal ActivityScheduledRecord(Guid instanceId, ActivityInstance instance, ActivityInfo child)
|
||||
: base(instanceId)
|
||||
{
|
||||
Fx.Assert(child != null, "Child activity cannot be null.");
|
||||
if (instance != null)
|
||||
{
|
||||
this.Activity = new ActivityInfo(instance);
|
||||
}
|
||||
this.Child = child;
|
||||
}
|
||||
|
||||
//parameter activity is null if the root activity is being scheduled.
|
||||
public ActivityScheduledRecord(
|
||||
Guid instanceId,
|
||||
long recordNumber,
|
||||
ActivityInfo activity,
|
||||
ActivityInfo child)
|
||||
: base(instanceId, recordNumber)
|
||||
{
|
||||
if (child == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("child");
|
||||
}
|
||||
|
||||
this.Activity = activity;
|
||||
this.Child = child;
|
||||
}
|
||||
|
||||
ActivityScheduledRecord(ActivityScheduledRecord record)
|
||||
: base(record)
|
||||
{
|
||||
this.Activity = record.Activity;
|
||||
this.Child = record.Child;
|
||||
}
|
||||
|
||||
public ActivityInfo Activity
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.activity;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.activity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ActivityInfo Child
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.child;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.child = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember(Name = "Activity")]
|
||||
internal ActivityInfo SerializedActivity
|
||||
{
|
||||
get { return this.Activity; }
|
||||
set { this.Activity = value; }
|
||||
}
|
||||
|
||||
[DataMember(Name = "Child")]
|
||||
internal ActivityInfo SerializedChild
|
||||
{
|
||||
get { return this.Child; }
|
||||
set { this.Child = value; }
|
||||
}
|
||||
|
||||
protected internal override TrackingRecord Clone()
|
||||
{
|
||||
return new ActivityScheduledRecord(this);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture,
|
||||
"ActivityScheduledRecord {{ {0}, Activity {{ {1} }}, ChildActivity {{ {2} }} }}",
|
||||
base.ToString(),
|
||||
this.Activity == null ? "<null>" : this.Activity.ToString(),
|
||||
this.Child.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
public class ActivityStateQuery : TrackingQuery
|
||||
{
|
||||
Collection<string> arguments;
|
||||
Collection<string> states;
|
||||
Collection<string> variables;
|
||||
|
||||
public ActivityStateQuery()
|
||||
{
|
||||
this.ActivityName = "*";
|
||||
}
|
||||
|
||||
public string ActivityName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Collection<string> Arguments
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.arguments == null)
|
||||
{
|
||||
this.arguments = new Collection<string>();
|
||||
}
|
||||
|
||||
return this.arguments;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<string> Variables
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.variables == null)
|
||||
{
|
||||
this.variables = new Collection<string>();
|
||||
}
|
||||
|
||||
return this.variables;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<string> States
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.states == null)
|
||||
{
|
||||
this.states = new Collection<string>();
|
||||
}
|
||||
return this.states;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasStates
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.states != null && this.states.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.arguments != null && this.arguments.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasVariables
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.variables != null && this.variables.Count > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Runtime;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Diagnostics;
|
||||
|
||||
[Fx.Tag.XamlVisible(false)]
|
||||
[DataContract]
|
||||
public sealed class ActivityStateRecord : TrackingRecord
|
||||
{
|
||||
IDictionary<string, object> variables;
|
||||
IDictionary<string, object> arguments;
|
||||
ActivityInfo activity;
|
||||
string state;
|
||||
|
||||
static ReadOnlyCollection<string> wildcardCollection = new ReadOnlyCollection<string>(new List<string>(1) { "*" });
|
||||
|
||||
internal ActivityStateRecord(Guid instanceId, ActivityInstance instance, ActivityInstanceState state)
|
||||
: this(instanceId, new ActivityInfo(instance), state)
|
||||
{
|
||||
}
|
||||
|
||||
internal ActivityStateRecord(Guid instanceId, ActivityInfo activity, ActivityInstanceState state)
|
||||
: base(instanceId)
|
||||
{
|
||||
this.Activity = activity;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ActivityInstanceState.Executing:
|
||||
this.State = ActivityStates.Executing;
|
||||
break;
|
||||
case ActivityInstanceState.Closed:
|
||||
this.State = ActivityStates.Closed;
|
||||
break;
|
||||
case ActivityInstanceState.Canceled:
|
||||
this.State = ActivityStates.Canceled;
|
||||
break;
|
||||
case ActivityInstanceState.Faulted:
|
||||
this.State = ActivityStates.Faulted;
|
||||
break;
|
||||
default:
|
||||
throw Fx.AssertAndThrow("Invalid state value");
|
||||
}
|
||||
}
|
||||
|
||||
public ActivityStateRecord(
|
||||
Guid instanceId,
|
||||
long recordNumber,
|
||||
ActivityInfo activity,
|
||||
string state)
|
||||
: base(instanceId, recordNumber)
|
||||
{
|
||||
if (activity == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("activity");
|
||||
}
|
||||
if (string.IsNullOrEmpty(state))
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNullOrEmpty("state");
|
||||
}
|
||||
|
||||
this.Activity = activity;
|
||||
this.State = state;
|
||||
}
|
||||
|
||||
ActivityStateRecord(ActivityStateRecord record)
|
||||
: base(record)
|
||||
{
|
||||
this.Activity = record.Activity;
|
||||
this.State = record.State;
|
||||
if (record.variables != null)
|
||||
{
|
||||
if (record.variables == ActivityUtilities.EmptyParameters)
|
||||
{
|
||||
this.variables = ActivityUtilities.EmptyParameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.variables = new Dictionary<string, object>(record.variables);
|
||||
}
|
||||
}
|
||||
|
||||
if (record.arguments != null)
|
||||
{
|
||||
if (record.arguments == ActivityUtilities.EmptyParameters)
|
||||
{
|
||||
this.arguments = ActivityUtilities.EmptyParameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.arguments = new Dictionary<string, object>(record.arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ActivityInfo Activity
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.activity;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.activity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string State
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.state;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.state = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, object> Variables
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.variables == null)
|
||||
{
|
||||
this.variables = GetVariables(wildcardCollection);
|
||||
Fx.Assert(this.variables.IsReadOnly, "only readonly dictionary can be set for variables");
|
||||
}
|
||||
return this.variables;
|
||||
}
|
||||
|
||||
internal set
|
||||
{
|
||||
Fx.Assert(value.IsReadOnly, "only readonly dictionary can be set for variables");
|
||||
this.variables = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, object> Arguments
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.arguments == null)
|
||||
{
|
||||
this.arguments = GetArguments(wildcardCollection);
|
||||
Fx.Assert(this.arguments.IsReadOnly, "only readonly dictionary can be set for arguments");
|
||||
}
|
||||
return this.arguments;
|
||||
}
|
||||
|
||||
internal set
|
||||
{
|
||||
Fx.Assert(value.IsReadOnly, "only readonly dictionary can be set for arguments");
|
||||
this.arguments = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "variables")]
|
||||
internal IDictionary<string, object> SerializedVariables
|
||||
{
|
||||
get { return this.variables; }
|
||||
set { this.variables = value; }
|
||||
}
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "arguments")]
|
||||
internal IDictionary<string, object> SerializedArguments
|
||||
{
|
||||
get { return this.arguments; }
|
||||
set { this.arguments = value; }
|
||||
}
|
||||
|
||||
[DataMember(Name = "Activity")]
|
||||
internal ActivityInfo SerializedActivity
|
||||
{
|
||||
get { return this.Activity; }
|
||||
set { this.Activity = value; }
|
||||
}
|
||||
|
||||
[DataMember(Name = "State")]
|
||||
internal string SerializedState
|
||||
{
|
||||
get { return this.State; }
|
||||
set { this.State = value; }
|
||||
}
|
||||
|
||||
protected internal override TrackingRecord Clone()
|
||||
{
|
||||
return new ActivityStateRecord(this);
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture,
|
||||
"ActivityStateRecord {{ {0}, Activity {{ {1} }}, State = {2} }}",
|
||||
base.ToString(),
|
||||
this.Activity.ToString(),
|
||||
this.State);
|
||||
}
|
||||
|
||||
internal IDictionary<string, object> GetVariables(ICollection<string> variables)
|
||||
{
|
||||
Dictionary<string, object> trackedVariables = null; // delay allocated through TrackData
|
||||
ActivityInstance currentInstance = this.Activity.Instance;
|
||||
|
||||
if (currentInstance != null)
|
||||
{
|
||||
Activity currentElement = currentInstance.Activity;
|
||||
Activity startActivity = currentInstance.Activity;
|
||||
bool containsWildcard = variables.Contains("*");
|
||||
//count defines how many items we can get in this lookup. It represents the maximum number of items that can be extracted,
|
||||
//if * is specified, any other names specified are expected to be variables defined in scope, not in the activity itself.
|
||||
//if a variable name in the activity is specified, the lookup continues through the variables in scope.
|
||||
int count = containsWildcard ? currentElement.RuntimeVariables.Count + variables.Count - 1 : variables.Count;
|
||||
|
||||
IdSpace activityIdSpace = currentElement.MemberOf;
|
||||
|
||||
while (currentInstance != null)
|
||||
{
|
||||
//* only extracts variables of the current Activity and not variables in scope.
|
||||
bool useWildCard = containsWildcard && startActivity == currentElement;
|
||||
|
||||
// we only track public Variables, not ImplementationVariables
|
||||
for (int i = 0; i < currentElement.RuntimeVariables.Count; i++)
|
||||
{
|
||||
Variable variable = currentElement.RuntimeVariables[i];
|
||||
if (TrackData(variable.Name, variable.Id, currentInstance, variables, useWildCard, ref trackedVariables))
|
||||
{
|
||||
if (trackedVariables.Count == count)
|
||||
{
|
||||
return new ReadOnlyDictionaryInternal<string, object>(trackedVariables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool foundNext = false;
|
||||
|
||||
while (!foundNext)
|
||||
{
|
||||
currentInstance = currentInstance.Parent;
|
||||
|
||||
if (currentInstance != null)
|
||||
{
|
||||
currentElement = currentInstance.Activity;
|
||||
foundNext = currentElement.MemberOf.Equals(activityIdSpace);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We set foundNext to true to get out of our loop.
|
||||
foundNext = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trackedVariables == null)
|
||||
{
|
||||
return ActivityUtilities.EmptyParameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
Fx.Assert(trackedVariables.Count > 0, "we should only allocate the dictionary if we're putting data in it");
|
||||
return new ReadOnlyDictionaryInternal<string, object>(trackedVariables);
|
||||
}
|
||||
}
|
||||
|
||||
internal IDictionary<string, object> GetArguments(ICollection<string> arguments)
|
||||
{
|
||||
Dictionary<string, object> trackedArguments = null; // delay allocated through TrackData
|
||||
ActivityInstance currentInstance = this.Activity.Instance;
|
||||
|
||||
if (currentInstance != null)
|
||||
{
|
||||
Activity currentElement = currentInstance.Activity;
|
||||
bool containsWildcard = arguments.Contains("*");
|
||||
int count = containsWildcard ? currentElement.RuntimeArguments.Count : arguments.Count;
|
||||
bool isActivityStateExecuting = ActivityStates.Executing.Equals(this.State, StringComparison.Ordinal);
|
||||
|
||||
//look at arguments for this element.
|
||||
for (int i = 0; i < currentElement.RuntimeArguments.Count; i++)
|
||||
{
|
||||
RuntimeArgument argument = currentElement.RuntimeArguments[i];
|
||||
|
||||
// OutArguments will always start with default(T), so there is no need to track them when state == Executing
|
||||
if (isActivityStateExecuting && argument.Direction == ArgumentDirection.Out)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TrackData(argument.Name, argument.Id, currentInstance, arguments, containsWildcard, ref trackedArguments))
|
||||
{
|
||||
if (trackedArguments.Count == count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trackedArguments == null)
|
||||
{
|
||||
return ActivityUtilities.EmptyParameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
Fx.Assert(trackedArguments.Count > 0, "we should only allocate the dictionary if we're putting data in it");
|
||||
return new ReadOnlyDictionaryInternal<string, object>(trackedArguments);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool TrackData(string name, int id, ActivityInstance currentInstance, ICollection<string> data, bool wildcard, ref Dictionary<string, object> trackedData)
|
||||
{
|
||||
if (wildcard || data.Contains(name))
|
||||
{
|
||||
Location location = currentInstance.Environment.GetSpecificLocation(id);
|
||||
if (location != null)
|
||||
{
|
||||
if (trackedData == null)
|
||||
{
|
||||
trackedData = new Dictionary<string, object>(10);
|
||||
}
|
||||
|
||||
string dataName = name ?? NameGenerator.Next();
|
||||
trackedData[dataName] = location.Value;
|
||||
if (TD.TrackingDataExtractedIsEnabled())
|
||||
{
|
||||
TD.TrackingDataExtracted(dataName, this.Activity.Name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
public static class ActivityStates
|
||||
{
|
||||
public const string Canceled = "Canceled";
|
||||
public const string Closed = "Closed";
|
||||
public const string Executing = "Executing";
|
||||
public const string Faulted = "Faulted";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
|
||||
public sealed class BookmarkResumptionQuery : TrackingQuery
|
||||
{
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime;
|
||||
|
||||
[Fx.Tag.XamlVisible(false)]
|
||||
[DataContract]
|
||||
public sealed class BookmarkResumptionRecord : TrackingRecord
|
||||
{
|
||||
Guid bookmarkScope;
|
||||
string bookmarkName;
|
||||
object payload;
|
||||
ActivityInfo owner;
|
||||
|
||||
internal BookmarkResumptionRecord(Guid instanceId, Bookmark bookmark, ActivityInstance ownerInstance, object payload)
|
||||
: base(instanceId)
|
||||
{
|
||||
if (bookmark.Scope != null)
|
||||
{
|
||||
this.BookmarkScope = bookmark.Scope.Id;
|
||||
}
|
||||
|
||||
if (bookmark.IsNamed)
|
||||
{
|
||||
this.BookmarkName = bookmark.Name;
|
||||
}
|
||||
|
||||
this.Owner = new ActivityInfo(ownerInstance);
|
||||
this.Payload = payload;
|
||||
}
|
||||
|
||||
public BookmarkResumptionRecord(Guid instanceId, long recordNumber, Guid bookmarkScope, string bookmarkName, ActivityInfo owner)
|
||||
: base(instanceId, recordNumber)
|
||||
{
|
||||
if (owner == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("owner");
|
||||
}
|
||||
|
||||
this.BookmarkScope = bookmarkScope;
|
||||
this.BookmarkName = bookmarkName;
|
||||
this.Owner = owner;
|
||||
}
|
||||
|
||||
BookmarkResumptionRecord(BookmarkResumptionRecord record)
|
||||
: base(record)
|
||||
{
|
||||
this.BookmarkScope = record.BookmarkScope;
|
||||
this.Owner = record.Owner;
|
||||
this.BookmarkName = record.BookmarkName;
|
||||
this.Payload = record.Payload;
|
||||
}
|
||||
|
||||
public Guid BookmarkScope
|
||||
{
|
||||
get
|
||||
{
|
||||
return bookmarkScope;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.bookmarkScope = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string BookmarkName
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.bookmarkName;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.bookmarkName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public object Payload
|
||||
{
|
||||
get { return this.payload; }
|
||||
internal set { this.payload = value; }
|
||||
}
|
||||
|
||||
public ActivityInfo Owner
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.owner;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.owner = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "BookmarkScope")]
|
||||
internal Guid SerializedBookmarkScope
|
||||
{
|
||||
get { return this.BookmarkScope; }
|
||||
set { this.BookmarkScope = value; }
|
||||
}
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "BookmarkName")]
|
||||
internal string SerializedBookmarkName
|
||||
{
|
||||
get { return this.BookmarkName; }
|
||||
set { this.BookmarkName = value; }
|
||||
}
|
||||
|
||||
[DataMember(Name = "Payload")]
|
||||
internal object SerializedPayload
|
||||
{
|
||||
get { return this.Payload; }
|
||||
set { this.Payload = value; }
|
||||
}
|
||||
|
||||
[DataMember(Name = "Owner")]
|
||||
internal ActivityInfo SerializedOwner
|
||||
{
|
||||
get { return this.Owner; }
|
||||
set { this.Owner = value; }
|
||||
}
|
||||
|
||||
protected internal override TrackingRecord Clone()
|
||||
{
|
||||
return new BookmarkResumptionRecord(this);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture,
|
||||
"BookmarkResumptionRecord {{ {0}, BookmarkName = {1}, BookmarkScope = {2}, OwnerActivity {{ {3} }} }}",
|
||||
base.ToString(),
|
||||
this.BookmarkName ?? "<null>",
|
||||
this.BookmarkScope,
|
||||
this.Owner.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
public sealed class CancelRequestedQuery : TrackingQuery
|
||||
{
|
||||
public CancelRequestedQuery()
|
||||
{
|
||||
this.ActivityName = "*";
|
||||
this.ChildActivityName = "*";
|
||||
}
|
||||
|
||||
public string ActivityName { get; set; }
|
||||
public string ChildActivityName { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime;
|
||||
using System.Globalization;
|
||||
|
||||
[Fx.Tag.XamlVisible(false)]
|
||||
[DataContract]
|
||||
public sealed class CancelRequestedRecord : TrackingRecord
|
||||
{
|
||||
ActivityInfo activity;
|
||||
ActivityInfo child;
|
||||
|
||||
internal CancelRequestedRecord(Guid instanceId, ActivityInstance instance, ActivityInstance child)
|
||||
: base(instanceId)
|
||||
{
|
||||
Fx.Assert(child != null, "Child activity instance cannot be null.");
|
||||
if (instance != null)
|
||||
{
|
||||
this.Activity = new ActivityInfo(instance);
|
||||
}
|
||||
this.Child = new ActivityInfo(child);
|
||||
}
|
||||
|
||||
//parameter activity is null if the root activity is being cancelled.
|
||||
public CancelRequestedRecord(
|
||||
Guid instanceId,
|
||||
long recordNumber,
|
||||
ActivityInfo activity,
|
||||
ActivityInfo child)
|
||||
: base(instanceId, recordNumber)
|
||||
{
|
||||
if (child == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNullOrEmpty("child");
|
||||
}
|
||||
|
||||
this.Activity = activity;
|
||||
this.Child = child;
|
||||
}
|
||||
|
||||
CancelRequestedRecord(CancelRequestedRecord record)
|
||||
: base(record)
|
||||
{
|
||||
this.Activity = record.Activity;
|
||||
this.Child = record.Child;
|
||||
}
|
||||
|
||||
public ActivityInfo Activity
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.activity;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.activity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ActivityInfo Child
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.child;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.child = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember(Name = "Activity")]
|
||||
internal ActivityInfo SerializedActivity
|
||||
{
|
||||
get { return this.Activity; }
|
||||
set { this.Activity = value; }
|
||||
}
|
||||
|
||||
[DataMember(Name = "Child")]
|
||||
internal ActivityInfo SerializedChild
|
||||
{
|
||||
get { return this.Child; }
|
||||
set { this.Child = value; }
|
||||
}
|
||||
|
||||
protected internal override TrackingRecord Clone()
|
||||
{
|
||||
return new CancelRequestedRecord(this);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture,
|
||||
"CancelRequestedRecord {{ {0}, Activity {{ {1} }}, ChildActivity {{ {2} }} }}",
|
||||
base.ToString(),
|
||||
this.Activity != null ? this.Activity.ToString() : "<null>",
|
||||
this.Child.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
public class CustomTrackingQuery : TrackingQuery
|
||||
{
|
||||
|
||||
public CustomTrackingQuery()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string ActivityName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
[DataContract]
|
||||
[Fx.Tag.XamlVisible(false)]
|
||||
public class CustomTrackingRecord : TrackingRecord
|
||||
{
|
||||
IDictionary<string, object> data;
|
||||
string name;
|
||||
ActivityInfo activity;
|
||||
|
||||
public CustomTrackingRecord(string name)
|
||||
: this(name, TraceLevel.Info)
|
||||
{
|
||||
}
|
||||
|
||||
public CustomTrackingRecord(string name, TraceLevel level)
|
||||
: this(Guid.Empty, name, level)
|
||||
{
|
||||
}
|
||||
|
||||
public CustomTrackingRecord(Guid instanceId, string name, TraceLevel level)
|
||||
: base(instanceId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("name");
|
||||
}
|
||||
this.Name = name;
|
||||
this.Level = level;
|
||||
}
|
||||
|
||||
protected CustomTrackingRecord(CustomTrackingRecord record)
|
||||
: base(record)
|
||||
{
|
||||
this.Name = record.Name;
|
||||
this.Activity = record.Activity;
|
||||
if (record.data != null && record.data.Count > 0)
|
||||
{
|
||||
foreach (KeyValuePair<string, object> item in record.data)
|
||||
{
|
||||
this.Data.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.name = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ActivityInfo Activity
|
||||
{
|
||||
get { return this.activity; }
|
||||
internal set { this.activity = value; }
|
||||
}
|
||||
|
||||
public IDictionary<string, object> Data
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.data == null)
|
||||
{
|
||||
this.data = new Dictionary<string, object>();
|
||||
}
|
||||
return this.data;
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "data")]
|
||||
internal IDictionary<string, object> SerializedData
|
||||
{
|
||||
get { return this.data; }
|
||||
set { this.data = value; }
|
||||
}
|
||||
|
||||
[DataMember(Name = "Name")]
|
||||
internal string SerializedName
|
||||
{
|
||||
get { return this.Name; }
|
||||
set { this.Name = value; }
|
||||
}
|
||||
|
||||
[DataMember(Name = "Activity")]
|
||||
internal ActivityInfo SerializedActivity
|
||||
{
|
||||
get { return this.Activity; }
|
||||
set { this.Activity = value; }
|
||||
}
|
||||
|
||||
protected internal override TrackingRecord Clone()
|
||||
{
|
||||
return new CustomTrackingRecord(this);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture,
|
||||
"CustomTrackingRecord {{ {0}, Name={1}, Activity {{ {2} }}, Level = {3} }}",
|
||||
base.ToString(),
|
||||
this.Name,
|
||||
this.Activity == null ? "<null>" : this.Activity.ToString(),
|
||||
this.Level);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,19 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
public sealed class FaultPropagationQuery : TrackingQuery
|
||||
{
|
||||
public FaultPropagationQuery()
|
||||
{
|
||||
this.FaultSourceActivityName = "*";
|
||||
this.FaultHandlerActivityName = "*";
|
||||
}
|
||||
|
||||
public string FaultHandlerActivityName { get; set; }
|
||||
|
||||
public string FaultSourceActivityName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
[Fx.Tag.XamlVisible(false)]
|
||||
[DataContract]
|
||||
public sealed class FaultPropagationRecord : TrackingRecord
|
||||
{
|
||||
ActivityInfo faultSource;
|
||||
ActivityInfo faultHandler;
|
||||
bool isFaultSource;
|
||||
Exception fault;
|
||||
|
||||
internal FaultPropagationRecord(Guid instanceId, ActivityInstance source, ActivityInstance faultHandler, bool isFaultSource, Exception fault)
|
||||
: base(instanceId)
|
||||
{
|
||||
Fx.Assert(source != null, "Fault source cannot be null");
|
||||
this.FaultSource = new ActivityInfo(source);
|
||||
|
||||
if (faultHandler != null)
|
||||
{
|
||||
this.FaultHandler = new ActivityInfo(faultHandler);
|
||||
}
|
||||
this.IsFaultSource = isFaultSource;
|
||||
this.Fault = fault;
|
||||
this.Level = TraceLevel.Warning;
|
||||
}
|
||||
|
||||
//parameter faultHandler is null if there are no handlers
|
||||
public FaultPropagationRecord(
|
||||
Guid instanceId,
|
||||
long recordNumber,
|
||||
ActivityInfo faultSource,
|
||||
ActivityInfo faultHandler,
|
||||
bool isFaultSource,
|
||||
Exception fault)
|
||||
: base(instanceId, recordNumber)
|
||||
{
|
||||
if (faultSource == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNullOrEmpty("faultSource");
|
||||
}
|
||||
|
||||
this.FaultSource = faultSource;
|
||||
this.FaultHandler = faultHandler;
|
||||
this.IsFaultSource = isFaultSource;
|
||||
this.Fault = fault;
|
||||
this.Level = TraceLevel.Warning;
|
||||
}
|
||||
|
||||
FaultPropagationRecord(FaultPropagationRecord record)
|
||||
: base(record)
|
||||
{
|
||||
this.FaultSource = record.FaultSource;
|
||||
this.FaultHandler = record.FaultHandler;
|
||||
this.Fault = record.Fault;
|
||||
this.IsFaultSource = record.IsFaultSource;
|
||||
}
|
||||
|
||||
public ActivityInfo FaultSource
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.faultSource;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.faultSource = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ActivityInfo FaultHandler
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.faultHandler;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.faultHandler = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsFaultSource
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.isFaultSource;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.isFaultSource = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Exception Fault
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.fault;
|
||||
}
|
||||
private set
|
||||
{
|
||||
this.fault = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember(Name = "FaultSource")]
|
||||
internal ActivityInfo SerializedFaultSource
|
||||
{
|
||||
get { return this.FaultSource; }
|
||||
set { this.FaultSource = value; }
|
||||
}
|
||||
|
||||
[DataMember(Name = "FaultHandler")]
|
||||
internal ActivityInfo SerializedFaultHandler
|
||||
{
|
||||
get { return this.FaultHandler; }
|
||||
set { this.FaultHandler = value; }
|
||||
}
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "IsFaultSource")]
|
||||
internal bool SerializedIsFaultSource
|
||||
{
|
||||
get { return this.IsFaultSource; }
|
||||
set { this.IsFaultSource = value; }
|
||||
}
|
||||
|
||||
[DataMember(Name = "Fault")]
|
||||
internal Exception SerializedFault
|
||||
{
|
||||
get { return this.Fault; }
|
||||
set { this.Fault = value; }
|
||||
}
|
||||
|
||||
protected internal override TrackingRecord Clone()
|
||||
{
|
||||
return new FaultPropagationRecord(this);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture,
|
||||
"FaultPropagationRecord {{ {0}, FaultSource {{ {1} }}, FaultHandler {{ {2} }}, IsFaultSource = {3} }}",
|
||||
base.ToString(),
|
||||
this.FaultSource.ToString(),
|
||||
this.FaultHandler != null ? this.FaultHandler.ToString() : "<null>",
|
||||
this.IsFaultSource);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
public enum ImplementationVisibility
|
||||
{
|
||||
RootScope,
|
||||
All
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,86 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
using System;
|
||||
using System.Runtime;
|
||||
|
||||
public abstract class TrackingParticipant
|
||||
{
|
||||
protected TrackingParticipant()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual TrackingProfile TrackingProfile
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Fx.Tag.InheritThrows(From = "Track", FromDeclaringType = typeof(TrackingParticipant))]
|
||||
protected internal virtual IAsyncResult BeginTrack(TrackingRecord record, TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
return new TrackAsyncResult(this, record, timeout, callback, state);
|
||||
}
|
||||
|
||||
[Fx.Tag.InheritThrows(From = "Track", FromDeclaringType = typeof(TrackingParticipant))]
|
||||
protected internal virtual void EndTrack(IAsyncResult result)
|
||||
{
|
||||
TrackAsyncResult.End(result);
|
||||
}
|
||||
|
||||
[Fx.Tag.Throws(typeof(Exception), "extensibility point")]
|
||||
[Fx.Tag.Throws.Timeout("Tracking data could not be saved before the timeout")]
|
||||
protected internal abstract void Track(TrackingRecord record, TimeSpan timeout);
|
||||
|
||||
class TrackAsyncResult : AsyncResult
|
||||
{
|
||||
static Action<object> asyncExecuteTrack = new Action<object>(ExecuteTrack);
|
||||
TrackingParticipant participant;
|
||||
TrackingRecord record;
|
||||
TimeSpan timeout;
|
||||
|
||||
public TrackAsyncResult(TrackingParticipant participant, TrackingRecord record, TimeSpan timeout, AsyncCallback callback, object state)
|
||||
: base(callback, state)
|
||||
{
|
||||
this.participant = participant;
|
||||
this.record = record;
|
||||
this.timeout = timeout;
|
||||
ActionItem.Schedule(asyncExecuteTrack, this);
|
||||
}
|
||||
|
||||
public static void End(IAsyncResult result)
|
||||
{
|
||||
AsyncResult.End<TrackAsyncResult>(result);
|
||||
}
|
||||
|
||||
static void ExecuteTrack(object state)
|
||||
{
|
||||
TrackAsyncResult thisPtr = (TrackAsyncResult)state;
|
||||
thisPtr.TrackCore();
|
||||
}
|
||||
|
||||
void TrackCore()
|
||||
{
|
||||
Exception participantException = null;
|
||||
try
|
||||
{
|
||||
this.participant.Track(this.record, this.timeout);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (Fx.IsFatal(exception))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
participantException = exception;
|
||||
}
|
||||
base.Complete(false, participantException);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Markup;
|
||||
|
||||
[ContentProperty("Queries")]
|
||||
public class TrackingProfile
|
||||
{
|
||||
Collection<TrackingQuery> queries;
|
||||
|
||||
public TrackingProfile()
|
||||
{
|
||||
}
|
||||
|
||||
[DefaultValue(null)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[DefaultValue(ImplementationVisibility.RootScope)]
|
||||
public ImplementationVisibility ImplementationVisibility { get; set; }
|
||||
|
||||
[DefaultValue(null)]
|
||||
public string ActivityDefinitionId { get; set; }
|
||||
|
||||
public Collection<TrackingQuery> Queries
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.queries == null)
|
||||
{
|
||||
this.queries = new Collection<TrackingQuery>();
|
||||
}
|
||||
return this.queries;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,428 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.Activities.Tracking
|
||||
{
|
||||
using System;
|
||||
using System.Activities;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime;
|
||||
|
||||
class TrackingProvider
|
||||
{
|
||||
List<TrackingParticipant> trackingParticipants;
|
||||
Dictionary<TrackingParticipant, RuntimeTrackingProfile> profileSubscriptions;
|
||||
IList<TrackingRecord> pendingTrackingRecords;
|
||||
Activity definition;
|
||||
bool filterValuesSetExplicitly;
|
||||
Hashtable activitySubscriptions;
|
||||
|
||||
long nextTrackingRecordNumber;
|
||||
|
||||
public TrackingProvider(Activity definition)
|
||||
{
|
||||
this.definition = definition;
|
||||
this.ShouldTrack = true;
|
||||
this.ShouldTrackActivityStateRecords = true;
|
||||
this.ShouldTrackActivityStateRecordsExecutingState = true;
|
||||
this.ShouldTrackActivityStateRecordsClosedState = true;
|
||||
this.ShouldTrackBookmarkResumptionRecords = true;
|
||||
this.ShouldTrackActivityScheduledRecords = true;
|
||||
this.ShouldTrackCancelRequestedRecords = true;
|
||||
this.ShouldTrackFaultPropagationRecords = true;
|
||||
this.ShouldTrackWorkflowInstanceRecords = true;
|
||||
}
|
||||
|
||||
public bool HasPendingRecords
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.pendingTrackingRecords != null && this.pendingTrackingRecords.Count > 0)
|
||||
|| !this.filterValuesSetExplicitly;
|
||||
}
|
||||
}
|
||||
|
||||
public long NextTrackingRecordNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.nextTrackingRecordNumber;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShouldTrack
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool ShouldTrackWorkflowInstanceRecords
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool ShouldTrackBookmarkResumptionRecords
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool ShouldTrackActivityScheduledRecords
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool ShouldTrackActivityStateRecords
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool ShouldTrackActivityStateRecordsExecutingState
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool ShouldTrackActivityStateRecordsClosedState
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool ShouldTrackCancelRequestedRecords
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool ShouldTrackFaultPropagationRecords
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
long GetNextRecordNumber()
|
||||
{
|
||||
// We blindly do this. On the off chance that a workflow causes it to loop back
|
||||
// around it shouldn't cause the workflow to fail and the tracking information
|
||||
// will still be salvagable.
|
||||
return this.nextTrackingRecordNumber++;
|
||||
}
|
||||
|
||||
public void OnDeserialized(long nextTrackingRecordNumber)
|
||||
{
|
||||
this.nextTrackingRecordNumber = nextTrackingRecordNumber;
|
||||
}
|
||||
|
||||
public void AddRecord(TrackingRecord record)
|
||||
{
|
||||
if (this.pendingTrackingRecords == null)
|
||||
{
|
||||
this.pendingTrackingRecords = new List<TrackingRecord>();
|
||||
}
|
||||
|
||||
record.RecordNumber = GetNextRecordNumber();
|
||||
this.pendingTrackingRecords.Add(record);
|
||||
}
|
||||
|
||||
public void AddParticipant(TrackingParticipant participant)
|
||||
{
|
||||
if (this.trackingParticipants == null)
|
||||
{
|
||||
this.trackingParticipants = new List<TrackingParticipant>();
|
||||
this.profileSubscriptions = new Dictionary<TrackingParticipant, RuntimeTrackingProfile>();
|
||||
}
|
||||
this.trackingParticipants.Add(participant);
|
||||
}
|
||||
|
||||
public void ClearParticipants()
|
||||
{
|
||||
this.trackingParticipants = null;
|
||||
this.profileSubscriptions = null;
|
||||
}
|
||||
|
||||
public void FlushPendingRecords(TimeSpan timeout)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.HasPendingRecords)
|
||||
{
|
||||
TimeoutHelper helper = new TimeoutHelper(timeout);
|
||||
for (int i = 0; i < this.trackingParticipants.Count; i++)
|
||||
{
|
||||
TrackingParticipant participant = this.trackingParticipants[i];
|
||||
RuntimeTrackingProfile runtimeProfile = GetRuntimeTrackingProfile(participant);
|
||||
|
||||
// HasPendingRecords can be true for the sole purpose of populating our initial profiles, so check again here
|
||||
if (this.pendingTrackingRecords != null)
|
||||
{
|
||||
for (int j = 0; j < this.pendingTrackingRecords.Count; j++)
|
||||
{
|
||||
TrackingRecord currentRecord = this.pendingTrackingRecords[j];
|
||||
Fx.Assert(currentRecord != null, "We should never come across a null context.");
|
||||
|
||||
TrackingRecord preparedRecord = null;
|
||||
bool shouldClone = this.trackingParticipants.Count > 1;
|
||||
if (runtimeProfile == null)
|
||||
{
|
||||
preparedRecord = shouldClone ? currentRecord.Clone() : currentRecord;
|
||||
}
|
||||
else
|
||||
{
|
||||
preparedRecord = runtimeProfile.Match(currentRecord, shouldClone);
|
||||
}
|
||||
|
||||
if (preparedRecord != null)
|
||||
{
|
||||
participant.Track(preparedRecord, helper.RemainingTime());
|
||||
if (TD.TrackingRecordRaisedIsEnabled())
|
||||
{
|
||||
TD.TrackingRecordRaised(preparedRecord.ToString(), participant.GetType().ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Note that if we fail to track yet the workflow manages to recover
|
||||
// we will attempt to track those records again.
|
||||
ClearPendingRecords();
|
||||
}
|
||||
}
|
||||
|
||||
public IAsyncResult BeginFlushPendingRecords(TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
return new FlushPendingRecordsAsyncResult(this, timeout, callback, state);
|
||||
}
|
||||
|
||||
public void EndFlushPendingRecords(IAsyncResult result)
|
||||
{
|
||||
FlushPendingRecordsAsyncResult.End(result);
|
||||
}
|
||||
|
||||
public bool ShouldTrackActivity(string name)
|
||||
{
|
||||
return this.activitySubscriptions == null || this.activitySubscriptions.ContainsKey(name) || this.activitySubscriptions.ContainsKey("*");
|
||||
}
|
||||
|
||||
void ClearPendingRecords()
|
||||
{
|
||||
if (this.pendingTrackingRecords != null)
|
||||
{
|
||||
//since the number of records is small, it is faster to remove from end than to call List.Clear
|
||||
for (int i = this.pendingTrackingRecords.Count - 1; i >= 0; i--)
|
||||
{
|
||||
this.pendingTrackingRecords.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RuntimeTrackingProfile GetRuntimeTrackingProfile(TrackingParticipant participant)
|
||||
{
|
||||
TrackingProfile profile;
|
||||
RuntimeTrackingProfile runtimeProfile;
|
||||
|
||||
if (!this.profileSubscriptions.TryGetValue(participant, out runtimeProfile))
|
||||
{
|
||||
profile = participant.TrackingProfile;
|
||||
|
||||
if (profile != null)
|
||||
{
|
||||
runtimeProfile = RuntimeTrackingProfile.GetRuntimeTrackingProfile(profile, this.definition);
|
||||
Merge(runtimeProfile.Filter);
|
||||
|
||||
//Add the names to the list of activities that have subscriptions. This provides a quick lookup
|
||||
//for the runtime to check if a TrackingRecord has to be created.
|
||||
IEnumerable<string> activityNames = runtimeProfile.GetSubscribedActivityNames();
|
||||
if (activityNames != null)
|
||||
{
|
||||
if (this.activitySubscriptions == null)
|
||||
{
|
||||
this.activitySubscriptions = new Hashtable();
|
||||
}
|
||||
foreach (string name in activityNames)
|
||||
{
|
||||
if (this.activitySubscriptions[name] == null)
|
||||
{
|
||||
this.activitySubscriptions[name] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//for null profiles, set all the filter flags.
|
||||
Merge(new TrackingRecordPreFilter(true));
|
||||
}
|
||||
|
||||
this.profileSubscriptions.Add(participant, runtimeProfile);
|
||||
}
|
||||
return runtimeProfile;
|
||||
}
|
||||
|
||||
void Merge(TrackingRecordPreFilter filter)
|
||||
{
|
||||
if (!this.filterValuesSetExplicitly)
|
||||
{
|
||||
// This it the first filter we are merging
|
||||
this.filterValuesSetExplicitly = true;
|
||||
|
||||
this.ShouldTrackActivityStateRecordsExecutingState = filter.TrackActivityStateRecordsExecutingState;
|
||||
this.ShouldTrackActivityScheduledRecords = filter.TrackActivityScheduledRecords;
|
||||
this.ShouldTrackActivityStateRecords = filter.TrackActivityStateRecords;
|
||||
this.ShouldTrackActivityStateRecordsClosedState = filter.TrackActivityStateRecordsClosedState;
|
||||
this.ShouldTrackBookmarkResumptionRecords = filter.TrackBookmarkResumptionRecords;
|
||||
this.ShouldTrackCancelRequestedRecords = filter.TrackCancelRequestedRecords;
|
||||
this.ShouldTrackFaultPropagationRecords = filter.TrackFaultPropagationRecords;
|
||||
this.ShouldTrackWorkflowInstanceRecords = filter.TrackWorkflowInstanceRecords;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ShouldTrackActivityStateRecordsExecutingState |= filter.TrackActivityStateRecordsExecutingState;
|
||||
this.ShouldTrackActivityScheduledRecords |= filter.TrackActivityScheduledRecords;
|
||||
this.ShouldTrackActivityStateRecords |= filter.TrackActivityStateRecords;
|
||||
this.ShouldTrackActivityStateRecordsClosedState |= filter.TrackActivityStateRecordsClosedState;
|
||||
this.ShouldTrackBookmarkResumptionRecords |= filter.TrackBookmarkResumptionRecords;
|
||||
this.ShouldTrackCancelRequestedRecords |= filter.TrackCancelRequestedRecords;
|
||||
this.ShouldTrackFaultPropagationRecords |= filter.TrackFaultPropagationRecords;
|
||||
this.ShouldTrackWorkflowInstanceRecords |= filter.TrackWorkflowInstanceRecords;
|
||||
}
|
||||
}
|
||||
|
||||
class FlushPendingRecordsAsyncResult : AsyncResult
|
||||
{
|
||||
static AsyncCompletion trackingCompleteCallback = new AsyncCompletion(OnTrackingComplete);
|
||||
|
||||
int currentRecord;
|
||||
int currentParticipant;
|
||||
TrackingProvider provider;
|
||||
TimeoutHelper timeoutHelper;
|
||||
|
||||
public FlushPendingRecordsAsyncResult(TrackingProvider provider, TimeSpan timeout, AsyncCallback callback, object state)
|
||||
: base(callback, state)
|
||||
{
|
||||
this.provider = provider;
|
||||
this.timeoutHelper = new TimeoutHelper(timeout);
|
||||
|
||||
if (RunLoop())
|
||||
{
|
||||
Complete(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool RunLoop()
|
||||
{
|
||||
if (this.provider.HasPendingRecords)
|
||||
{
|
||||
while (this.currentParticipant < this.provider.trackingParticipants.Count)
|
||||
{
|
||||
TrackingParticipant participant = this.provider.trackingParticipants[this.currentParticipant];
|
||||
RuntimeTrackingProfile runtimeProfile = this.provider.GetRuntimeTrackingProfile(participant);
|
||||
|
||||
if (this.provider.pendingTrackingRecords != null)
|
||||
{
|
||||
while (this.currentRecord < this.provider.pendingTrackingRecords.Count)
|
||||
{
|
||||
bool completedSynchronously = PostTrackingRecord(participant, runtimeProfile);
|
||||
if (!completedSynchronously)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.currentRecord = 0;
|
||||
this.currentParticipant++;
|
||||
}
|
||||
}
|
||||
|
||||
// We've now tracked all of the records.
|
||||
this.provider.ClearPendingRecords();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool OnTrackingComplete(IAsyncResult result)
|
||||
{
|
||||
Fx.Assert(!result.CompletedSynchronously, "TrackingAsyncResult.OnTrackingComplete should not get called with a result that is CompletedSynchronously");
|
||||
|
||||
FlushPendingRecordsAsyncResult thisPtr = (FlushPendingRecordsAsyncResult)result.AsyncState;
|
||||
TrackingParticipant participant = thisPtr.provider.trackingParticipants[thisPtr.currentParticipant];
|
||||
bool isSuccessful = false;
|
||||
try
|
||||
{
|
||||
participant.EndTrack(result);
|
||||
isSuccessful = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!isSuccessful)
|
||||
{
|
||||
thisPtr.provider.ClearPendingRecords();
|
||||
}
|
||||
}
|
||||
return thisPtr.RunLoop();
|
||||
}
|
||||
|
||||
bool PostTrackingRecord(TrackingParticipant participant, RuntimeTrackingProfile runtimeProfile)
|
||||
{
|
||||
TrackingRecord originalRecord = this.provider.pendingTrackingRecords[this.currentRecord];
|
||||
this.currentRecord++;
|
||||
bool isSuccessful = false;
|
||||
|
||||
try
|
||||
{
|
||||
TrackingRecord preparedRecord = null;
|
||||
bool shouldClone = this.provider.trackingParticipants.Count > 1;
|
||||
if (runtimeProfile == null)
|
||||
{
|
||||
preparedRecord = shouldClone ? originalRecord.Clone() : originalRecord;
|
||||
}
|
||||
else
|
||||
{
|
||||
preparedRecord = runtimeProfile.Match(originalRecord, shouldClone);
|
||||
}
|
||||
|
||||
if (preparedRecord != null)
|
||||
{
|
||||
IAsyncResult result = participant.BeginTrack(preparedRecord, this.timeoutHelper.RemainingTime(), PrepareAsyncCompletion(trackingCompleteCallback), this);
|
||||
if (TD.TrackingRecordRaisedIsEnabled())
|
||||
{
|
||||
TD.TrackingRecordRaised(preparedRecord.ToString(), participant.GetType().ToString());
|
||||
}
|
||||
if (result.CompletedSynchronously)
|
||||
{
|
||||
participant.EndTrack(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
isSuccessful = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
isSuccessful = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!isSuccessful)
|
||||
{
|
||||
this.provider.ClearPendingRecords();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void End(IAsyncResult result)
|
||||
{
|
||||
AsyncResult.End<FlushPendingRecordsAsyncResult>(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user