如何获得WorkflowApplication的上下文?

时间:2012-07-09 14:28:09

标签: workflow-foundation-4

我正在制作类似于Visual Workflow Tracking *的Workflow设计器。

我想添加一个新控件来调试wf,但是id不知道如何访问wf上下文

运行WF我使用:

 WFApplication wfApp = new WorkflowApplication(act, inputs);

我的想法是当我回忆跟踪事件,获取wfApp的上下文,获取变量或参数值。

它的位置?

*您可以从以下位置下载VisualStudioTracking代码: Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 然后 :\ WF_WCF_Samples \ WF \ Application \ VisualWorkflowTracking *

3 个答案:

答案 0 :(得分:4)

最后我解决了这个问题。

首先,我从xaml获取所有参数名称和工作流变量。

    class XamlHelper
    {   

    private string xaml;

    public XamlHelper(string xaml)
    {           
        this.xaml = xaml;

        DynamicActivity act = GetRuntimeExecutionRoot(this.xaml);
        ArgumentNames = GetArgumentsNames(act);

     GetVariables(act);
    }

    private void GetVariables(DynamicActivity act)
    {
        Variables = new List<string>();
        InspectActivity(act);


    }

    private void InspectActivity(Activity root)
    {


        IEnumerator<Activity> activities =
            WorkflowInspectionServices.GetActivities(root).GetEnumerator();


        while (activities.MoveNext())
        {

            PropertyInfo propVars = activities.Current.GetType().GetProperties().FirstOrDefault(p => p.Name == "Variables" && p.PropertyType == typeof(Collection<Variable>));
            if (propVars != null)
            {
                try
                {
                    Collection<Variable> variables = (Collection<Variable>)propVars.GetValue(activities.Current, null);
                    variables.ToList().ForEach(v =>
                    {
                        Variables.Add(v.Name);

                    });
                }
                catch
                {

                }
            }
            InspectActivity(activities.Current);
        }
    }





    public List<string> Variables
    {
        get;
        private set;
    }

    public List<string> ArgumentNames
    {
        get;
        private set;
    }


    private DynamicActivity GetRuntimeExecutionRoot(string xaml)
    {


        Activity root = ActivityXamlServices.Load(new StringReader(xaml));


            WorkflowInspectionServices.CacheMetadata(root);

        return root as DynamicActivity;

    }

    private List<string> GetArgumentsNames(DynamicActivity act)
    {
        List<string> names = new List<string>();
        if (act != null)
        {
            act.Properties.Where(p => typeof(Argument).IsAssignableFrom(p.Type)).ToList().ForEach(dp =>
            {
                names.Add(dp.Name);
            });

        }

        return names;
    }

}

其次,我使用这些参数和变量名创建跟踪

    private static WFTrace CreateTrace(List<string> argumentNames, List<string> variablesNames)
    {
        WFTrace trace = new WFTrace();
        trace.TrackingProfile = new TrackingProfile()
        {
            ImplementationVisibility = ImplementationVisibility.All,
            Name = "CustomTrackingProfile",
            Queries = 
                {
                    new CustomTrackingQuery() 
                    {
                     Name = all,
                     ActivityName = all
                    },
                    new WorkflowInstanceQuery()
                    {


                         // Limit workflow instance tracking records for started and completed workflow states
                        States = {WorkflowInstanceStates.Started, WorkflowInstanceStates.Completed },
                   }
                }
        };

        trace.TrackingProfile.Queries.Add(GetActivityQueryState(argumentNames, variablesNames));

        return trace;
    }

然后调用wf并添加traceextension。

Adam这是代码

  private TrackingQuery GetActivityQueryState(List<string> argumentNames, List<string> variablesNames)
        {
            ActivityStateQuery query = new ActivityStateQuery()
            {
                ActivityName = "*",
                States = { ActivityStates.Executing, ActivityStates.Closed }
            };
            if (argumentNames != null)
            {
                argumentNames.Distinct().ToList().ForEach(arg =>
                {
                    query.Arguments.Add(arg);
                });
            }
            if (variablesNames != null)
            {
                variablesNames.Distinct().ToList().ForEach(v =>
                {
                    query.Variables.Add(v);
                });
            }
            return query;
        }

答案 1 :(得分:1)

您可以使用Tracking Participants在工作流程运行时提取variables and arguments

答案 2 :(得分:0)

我尝试使用此跟踪参与者跟踪变量

    private static VisualTrackingParticipant VisualTracking()
    {
        String all = "*";
        VisualTrackingParticipant simTracker = new VisualTrackingParticipant()
        {
            TrackingProfile = new TrackingProfile()
            {
                Name = "CustomTrackingProfile",
                Queries = 
                    {
                        new CustomTrackingQuery() 
                        {
                            Name = all,
                            ActivityName = all
                        },
                        new WorkflowInstanceQuery()
                        {
                            // Limit workflow instance tracking records for started and completed workflow states
                           // States = { WorkflowInstanceStates.Started, WorkflowInstanceStates.Completed },
                           States={all}
                        },
                        new ActivityStateQuery()
                        {
                            // Subscribe for track records from all activities for all states
                            ActivityName = all,
                            States = { all },

                            // Extract workflow variables and arguments as a part of the activity tracking record
                            // VariableName = "*" allows for extraction of all variables in the scope
                            // of the activity
                            Variables = 
                            {                                
                                { all }   
                            },
                            Arguments={ {all}}
                        }   
                    }
            }
        };
        return simTracker;
    }

这是VisualTrackingParticipant

public class VisualTrackingParticipant : System.Activities.Tracking.TrackingParticipant
{
    public event EventHandler<TrackingEventArgs> TrackingRecordReceived;
    public Dictionary<string, Activity> ActivityIdToWorkflowElementMap { get; set; }


    protected override void Track(TrackingRecord record, TimeSpan timeout)
    {
        OnTrackingRecordReceived(record, timeout);
    }

    //On Tracing Record Received call the TrackingRecordReceived with the record received information from the TrackingParticipant. 
    //We also do not worry about Expressions' tracking data
    protected void OnTrackingRecordReceived(TrackingRecord record, TimeSpan timeout)
    {
        System.Diagnostics.Debug.WriteLine(
            String.Format("Tracking Record Received: {0} with timeout: {1} seconds.", record, timeout.TotalSeconds)
        );

        if (TrackingRecordReceived != null)
        {
            ActivityStateRecord activityStateRecord = record as ActivityStateRecord;

            if//(
                (activityStateRecord != null)
            // && (!activityStateRecord.Activity.TypeName.Contains("System.Activities.Expressions")))
            {
                Activity act = null;
                ActivityIdToWorkflowElementMap.TryGetValue(activityStateRecord.Activity.Id, out act);


                TrackingRecordReceived(this, new TrackingEventArgs(
                                                record,
                                                timeout,
                                                act
                                                )

                    );


            }
            else
            {
                TrackingRecordReceived(this, new TrackingEventArgs(record, timeout, null));
            }

        }
    }
}

//Custom Tracking EventArgs
public class TrackingEventArgs : EventArgs
{
    public TrackingRecord Record {get; set;}
    public TimeSpan Timeout {get; set;}
    public Activity Activity { get; set; }

    public TrackingEventArgs(TrackingRecord trackingRecord, TimeSpan timeout, Activity activity)
    {
        this.Record = trackingRecord;
        this.Timeout = timeout;
        this.Activity = activity;
    }
}

如果我跟踪这个wf:

<Activity mc:Ignorable="sap" x:Class="Microsoft.Samples.Workflow" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sd1="clr-namespace:System.Data;assembly=System.Data.DataSetExtensions" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <x:Members>
    <x:Property Name="decisionVar" Type="InArgument(x:Boolean)" />
  </x:Members>
  <sap:VirtualizedContainerService.HintSize>666,676</sap:VirtualizedContainerService.HintSize>
  <mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>
  <Flowchart sad:XamlDebuggerXmlReader.FileName="C:\WF_WCF_Samples\WF\Application\VisualWorkflowTracking\CS\VisualWorkflowTracking\Workflow.xaml" sap:VirtualizedContainerService.HintSize="626,636" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces">
    <Flowchart.Variables>
      <Variable x:TypeArguments="x:String" Name="myStr" />
    </Flowchart.Variables>
    <sap:WorkflowViewStateService.ViewState>
      <scg3:Dictionary x:TypeArguments="x:String, x:Object">
        <x:Boolean x:Key="IsExpanded">False</x:Boolean>
        <av:Point x:Key="ShapeLocation">270,7.5</av:Point>
        <av:Size x:Key="ShapeSize">60,75</av:Size>
        <av:PointCollection x:Key="ConnectorLocation">300,82.5 300,111.5</av:PointCollection>
        <x:Double x:Key="Width">611.5</x:Double>
      </scg3:Dictionary>
    </sap:WorkflowViewStateService.ViewState>
    <Flowchart.StartNode>
      <FlowStep x:Name="__ReferenceID0">
        <sap:WorkflowViewStateService.ViewState>
          <scg3:Dictionary x:TypeArguments="x:String, x:Object">
            <av:Point x:Key="ShapeLocation">179,111.5</av:Point>
            <av:Size x:Key="ShapeSize">242,58</av:Size>
            <av:PointCollection x:Key="ConnectorLocation">300,169.5 300,199.5 280,199.5 280,269.5</av:PointCollection>
          </scg3:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
        <Assign sap:VirtualizedContainerService.HintSize="242,58">
          <Assign.To>
            <OutArgument x:TypeArguments="x:String">[myStr]</OutArgument>
          </Assign.To>
          <Assign.Value>
            <InArgument x:TypeArguments="x:String">PDC Rocks</InArgument>
          </Assign.Value>
        </Assign>
        <FlowStep.Next>
          <FlowStep x:Name="__ReferenceID1">
            <sap:WorkflowViewStateService.ViewState>
              <scg3:Dictionary x:TypeArguments="x:String, x:Object">
                <av:Point x:Key="ShapeLocation">174.5,269.5</av:Point>
                <av:Size x:Key="ShapeSize">211,61</av:Size>
                <av:PointCollection x:Key="ConnectorLocation">155.33,351.361666666667 155.33,481 204.5,481</av:PointCollection>
              </scg3:Dictionary>
            </sap:WorkflowViewStateService.ViewState>
            <WriteLine sap:VirtualizedContainerService.HintSize="211,61" Text="[myStr]" />
          </FlowStep>
        </FlowStep.Next>
      </FlowStep>
    </Flowchart.StartNode>
    <x:Reference>__ReferenceID0</x:Reference>
    <x:Reference>__ReferenceID1</x:Reference>
  </Flowchart>
</Activity>

当活动确定关闭y时,请回顾此跟踪

[Arg] Value = PDC Rocks [Arg] To = PDC Rocks

我不知道值的位置是var的名称