Microsoft.Activities.Extensions/Tracking/StateMachineStateTracker.cs
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="StateMachineStateTracker.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Microsoft.Activities.Extensions.Tracking
{
using System;
using System.Activities;
using System.Activities.DurableInstancing;
using System.Activities.Statements;
using System.Activities.Statements.Tracking;
using System.Activities.Tracking;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Text;
#if NET401_OR_GREATER
/// <summary>
/// The state machine state tracker.
/// </summary>
public class StateMachineStateTracker : TrackingParticipant
{
#region Constants and Fields
/// <summary>
/// The find existing instances sql.
/// </summary>
private const string FindExistingInstancesSql =
@"SELECT InstanceId, Value1
FROM [System.Activities.DurableInstancing].[InstancePromotedProperties]
WHERE PromotionName = '{0}'
AND Value2 = @ActivityID
AND Value3 = @DisplayName;";
private const string FindExistingInstanceSql =
@"SELECT InstanceId, Value1
FROM [System.Activities.DurableInstancing].[InstancePromotedProperties]
WHERE PromotionName = '{0}'
AND InstanceId = @InstanceId
AND Value2 = @ActivityID
AND Value3 = @DisplayName;";
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="StateMachineStateTracker"/> class.
/// </summary>
/// <param name="rootActivity">
/// The root Activity.
/// </param>
public StateMachineStateTracker(Activity rootActivity)
{
if (rootActivity == null)
{
throw new ArgumentNullException("rootActivity");
}
this.RootActivity = rootActivity;
this.TrackedStateMachines = new Dictionary<string, StateTrackerInfo>();
}
#endregion
#region Public Properties
/// <summary>
/// Gets CurrentState.
/// </summary>
public string CurrentState
{
get
{
return this.HasCurrentStateMachine()
? this.TrackedStateMachines[this.CurrentStateMachine].CurrentState
: null;
}
}
/// <summary>
/// Gets CurrentStateMachine.
/// </summary>
public string CurrentStateMachine { get; internal set; }
/// <summary>
/// Gets InstanceId.
/// </summary>
public Guid InstanceId { get; internal set; }
/// <summary>
/// Gets PossibleTransitions of the currently executing StateMachine.
/// </summary>
public string PossibleTransitions
{
get
{
return this.HasCurrentStateMachine()
? this.TrackedStateMachines[this.CurrentStateMachine].PossibleTransitions
: null;
}
}
/// <summary>
/// Gets RootActivity.
/// </summary>
public Activity RootActivity { get; private set; }
/// <summary>
/// Gets TrackedStateMachines.
/// </summary>
public Dictionary<string, StateTrackerInfo> TrackedStateMachines { get; private set; }
/// <summary>
/// Gets Transitions.
/// </summary>
public ICollection<Transition> Transitions
{
get
{
return this.HasCurrentStateMachine()
? this.TrackedStateMachines[this.CurrentStateMachine].Transitions
: null;
}
}
#endregion
#region Public Methods and Operators
/// <summary>
/// The load instances.
/// </summary>
/// <param name="rootActivity">
/// The root activity.
/// </param>
/// <param name="connectionString">
/// The connection string.
/// </param>
/// <returns>
/// </returns>
public static IEnumerable<StateMachineStateTracker> LoadInstances(
Activity rootActivity, string connectionString)
{
if (string.IsNullOrWhiteSpace(rootActivity.Id))
{
WorkflowInspectionServices.CacheMetadata(rootActivity);
}
try
{
using (var connection = new SqlConnection(connectionString))
{
var command =
new SqlCommand(
string.Format(FindExistingInstancesSql, StateTrackerPersistenceProvider.StateTrackerName),
connection);
command.Parameters.AddWithValue("@ActivityID", rootActivity.Id);
command.Parameters.AddWithValue("@DisplayName", rootActivity.DisplayName);
connection.Open();
var list = new List<StateMachineStateTracker>();
var dataReader = command.ExecuteReader();
while (dataReader.Read())
{
list.Add(
StateTrackerPersistenceProvider.Parse(
rootActivity, dataReader.GetGuid(0), dataReader.GetString(1)));
}
dataReader.Close();
return list;
}
}
catch (Exception exception)
{
System.Diagnostics.Trace.WriteLine(exception.Message);
}
return null;
}
/// <summary>
/// The load instances.
/// </summary>
/// <param name="instanceId">The instance Id </param>
/// <param name="rootActivity">
/// The root activity.
/// </param>
/// <param name="connectionString">
/// The connection string.
/// </param>
/// <returns>
/// </returns>
public static StateMachineStateTracker LoadInstance(Guid instanceId,
Activity rootActivity, string connectionString)
{
if (string.IsNullOrWhiteSpace(rootActivity.Id))
{
WorkflowInspectionServices.CacheMetadata(rootActivity);
}
try
{
using (var connection = new SqlConnection(connectionString))
{
var command =
new SqlCommand(
string.Format(FindExistingInstanceSql, StateTrackerPersistenceProvider.StateTrackerName),
connection);
command.Parameters.AddWithValue("@InstanceId", instanceId);
command.Parameters.AddWithValue("@ActivityID", rootActivity.Id);
command.Parameters.AddWithValue("@DisplayName", rootActivity.DisplayName);
connection.Open();
var dataReader = command.ExecuteReader();
dataReader.Read();
return StateTrackerPersistenceProvider.Parse(rootActivity, dataReader.GetGuid(0), dataReader.GetString(1));
}
}
catch (Exception exception)
{
System.Diagnostics.Trace.WriteLine(exception.Message);
}
return null;
}
/// <summary>
/// The promote.
/// </summary>
/// <param name="instanceStore">
/// The instance store.
/// </param>
public static void Promote(SqlWorkflowInstanceStore instanceStore)
{
StateTrackerPersistenceProvider.Promote(instanceStore);
}
/// <summary>
/// The trace.
/// </summary>
public void Trace()
{
var msg = new StringBuilder();
msg.AppendFormat(
"StateMachineStateTracker Tracking {0} state machine(s)\r\n", this.TrackedStateMachines.Count);
foreach (var stateInfo in this.TrackedStateMachines.Values)
{
msg.AppendFormat("StateMachine: {0}\r\n", stateInfo.StateMachineName);
msg.AppendFormat("\tCurrentState: {0}\r\n", stateInfo.CurrentState);
msg.AppendFormat("\tPossibleTransitions: {0}\r\n", stateInfo.PossibleTransitions);
}
System.Diagnostics.Trace.WriteLine(msg.ToString());
}
#endregion
#region Methods
/// <summary>
/// The track.
/// </summary>
/// <param name="record">
/// The record.
/// </param>
/// <param name="timeout">
/// The timeout.
/// </param>
protected override void Track(TrackingRecord record, TimeSpan timeout)
{
var smsr = record as StateMachineStateRecord;
if (smsr != null)
{
try
{
this.TrackedStateMachines.Remove(smsr.StateMachineName);
}
catch (KeyNotFoundException)
{
// Do nothing - this is ok
}
this.InstanceId = smsr.InstanceId;
var stateInfo = new StateTrackerInfo
{
CurrentState = smsr.StateName,
StateMachineName = smsr.StateMachineName,
Transitions = smsr.GetTransitions(this.RootActivity),
};
this.CurrentStateMachine = smsr.StateMachineName;
this.TrackedStateMachines.Add(smsr.StateMachineName, stateInfo);
}
else
{
var wir = record as WorkflowInstanceRecord;
if (wir != null)
{
switch (wir.GetState())
{
case WorkflowInstanceRecordState.Canceled:
this.Clear();
break;
case WorkflowInstanceRecordState.Completed:
this.Clear();
break;
}
}
}
}
/// <summary>
/// The clear.
/// </summary>
private void Clear()
{
this.TrackedStateMachines.Clear();
this.CurrentStateMachine = string.Empty;
}
/// <summary>
/// The has current state machine.
/// </summary>
/// <returns>
/// The has current state machine.
/// </returns>
private bool HasCurrentStateMachine()
{
return !string.IsNullOrWhiteSpace(this.CurrentStateMachine);
}
#endregion
/// <summary>
/// The state tracker info.
/// </summary>
public class StateTrackerInfo
{
#region Public Properties
/// <summary>
/// Gets CurrentState.
/// </summary>
public string CurrentState { get; internal set; }
/// <summary>
/// Gets PossibleTransitions.
/// </summary>
public string PossibleTransitions
{
get
{
var result = new StringBuilder();
foreach (var e in this.Transitions)
{
if (result.Length > 0)
{
result.Append(", ");
}
result.AppendFormat("{0}", e.DisplayName);
}
return result.ToString();
}
}
/// <summary>
/// Gets StateMachineName.
/// </summary>
public string StateMachineName { get; internal set; }
/// <summary>
/// Gets Transitions.
/// </summary>
public ICollection<Transition> Transitions { get; internal set; }
#endregion
}
}
#endif
}Microsoft.Activities.Extensions
Depedencies
| Name | AssemblyVersion | Culture | PublicKeyToken | Type |
|---|---|---|---|---|
| Microsoft.CSharp | 4.0.0.0 | neutral | b03f5f7f11d50a3a | Required |
| mscorlib | 4.0.0.0 | neutral | b77a5c561934e089 | Required |
| System | 4.0.0.0 | neutral | b77a5c561934e089 | Required |
| System.Activities | 4.0.0.0 | neutral | 31bf3856ad364e35 | Required |
| System.Activities.DurableInstancing | 4.0.0.0 | neutral | 31bf3856ad364e35 | Required |
| System.Configuration | 4.0.0.0 | neutral | b03f5f7f11d50a3a | Required |
| System.Core | 4.0.0.0 | neutral | b77a5c561934e089 | Required |
| System.Data | 4.0.0.0 | neutral | b77a5c561934e089 | Required |
| System.Runtime.DurableInstancing | 4.0.0.0 | neutral | 31bf3856ad364e35 | Required |
| System.ServiceModel | 4.0.0.0 | neutral | b77a5c561934e089 | Required |
| System.ServiceModel.Activities | 4.0.0.0 | neutral | 31bf3856ad364e35 | Required |
| System.Xaml | 4.0.0.0 | neutral | b77a5c561934e089 | Required |
| System.Xml | 4.0.0.0 | neutral | b77a5c561934e089 | Required |
| System.Xml.Linq | 4.0.0.0 | neutral | b77a5c561934e089 | Required |
Sources
| Path | Related |
|---|---|
| Microsoft.Activities.Extensions/ActivityContextExtensions.cs | Source |
| Microsoft.Activities.Extensions/ActivityXamlServicesEx.cs | Source |
| Microsoft.Activities.Extensions/BookmarkResumptionException.cs | Source |
| Microsoft.Activities.Extensions/CodeActivityMetadataExtensions.cs | Source |
| Microsoft.Activities.Extensions/Diagnostics/TraceTrackingParticipant.cs | Source |
| Microsoft.Activities.Extensions/Diagnostics/WorkflowApplicationIdleEventArgsDiagnostics.cs | Source |
| Microsoft.Activities.Extensions/Diagnostics/WorkflowServiceTraceBehavior.cs | Source |
| Microsoft.Activities.Extensions/Diagnostics/WorkflowServiceTraceElement.cs | Source |
| Microsoft.Activities.Extensions/InArgumentExtensions.cs | Source |
| Microsoft.Activities.Extensions/InputDictionary.cs | Source |
| Microsoft.Activities.Extensions/NativeActivityMetadataExtensions.cs | Source |
| Microsoft.Activities.Extensions/Occurance.cs | Source |
| Microsoft.Activities.Extensions/OutputDictionary.cs | Source |
| Microsoft.Activities.Extensions/ReflectionObject.cs | Source |
| Microsoft.Activities.Extensions/ServiceModel/ConfigurationElementCollection.cs | Source |
| Microsoft.Activities.Extensions/ServiceModel/SilverlightFaultBehavior.cs | Source |
| Microsoft.Activities.Extensions/ServiceModel/SilverlightFaultElement.cs | Source |
| Microsoft.Activities.Extensions/ServiceModel/StateMachineTrackingBehavior.cs | Source |
| Microsoft.Activities.Extensions/ServiceModel/StateMachineTrackingElement.cs | Source |
| Microsoft.Activities.Extensions/ServiceModel/WorkflowExtensionConfigElement.cs | Source |
| Microsoft.Activities.Extensions/ServiceModel/WorkflowExtensionsBehavior.cs | Source |
| Microsoft.Activities.Extensions/ServiceModel/WorkflowExtensionsElement.cs | Source |
| Microsoft.Activities.Extensions/SR.Designer.cs | Source |
| Microsoft.Activities.Extensions/Statements/AddToDictionary.cs | Source |
| Microsoft.Activities.Extensions/Statements/ClearDictionary.cs | Source |
| Microsoft.Activities.Extensions/Statements/DelayUntilDateTime.cs | Source |
| Microsoft.Activities.Extensions/Statements/DelayUntilTime.cs | Source |
| Microsoft.Activities.Extensions/Statements/GetFromDictionary.cs | Source |
| Microsoft.Activities.Extensions/Statements/InvokeWorkflow.cs | Source |
| Microsoft.Activities.Extensions/Statements/KeyExistsInDictionary.cs | Source |
| Microsoft.Activities.Extensions/Statements/LoadActivity.cs | Source |
| Microsoft.Activities.Extensions/Statements/LoadAndInvokeWorkflow.cs | Source |
| Microsoft.Activities.Extensions/Statements/LoadAssembly.cs | Source |
| Microsoft.Activities.Extensions/Statements/RemoveFromDictionary.cs | Source |
| Microsoft.Activities.Extensions/Statements/ValueExistsInDictionary.cs | Source |
| Microsoft.Activities.Extensions/StrictXamlHelper.cs | Source |
| Microsoft.Activities.Extensions/Tracking/ActivityScheduledRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/ActivityStateRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/BookmarkResumptionRecord.cs | Source |
| Microsoft.Activities.Extensions/Tracking/CancelRequestedRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/CustomTrackingRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/FaultPropagationRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/ListExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/ListTrackingParticipant.cs | Source |
| Microsoft.Activities.Extensions/Tracking/StateMachineStateRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/StateMachineStateTracker.cs | Source |
| Microsoft.Activities.Extensions/Tracking/StateTrackerPersistenceProvider.cs | Source |
| Microsoft.Activities.Extensions/Tracking/TrackingHelper.cs | Source |
| Microsoft.Activities.Extensions/Tracking/TrackingRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/WorkflowInstanceAbortedRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/WorkflowInstanceRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/WorkflowInstanceSuspendedRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/WorkflowInstanceTerminatedRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/Tracking/WorkflowInstanceUnhandledExceptionRecordExtensions.cs | Source |
| Microsoft.Activities.Extensions/WorkflowAbortedEpisodeResult.cs | Source |
| Microsoft.Activities.Extensions/WorkflowApplicationExtensions.cs | Source |
| Microsoft.Activities.Extensions/WorkflowApplicationIdleEventArgsEx.cs | Source |
| Microsoft.Activities.Extensions/WorkflowArguments.cs | Source |
| Microsoft.Activities.Extensions/WorkflowCompletedEpisodeResult.cs | Source |
| Microsoft.Activities.Extensions/WorkflowEpisode.cs | Source |
| Microsoft.Activities.Extensions/WorkflowIdleEpisodeResult.cs | Source |

