2

Visual Workflow Tracking* に似たワークフロー デザイナーを作成しています。

wf をデバッグする新しいコントロールを追加したいのですが、wf コンテキストにアクセスする方法がわかりません

WF を実行するには、これを使用します。

 WFApplication wfApp = new WorkflowApplication(act, inputs);

私の考えは、トレース イベントを受け取り、wfApp のコンテキストを取得して、変数または引数の値を取得することです。

それは可能ですか?

*VisualStudioTracking コード は、.NET Framework 4 用の Windows Communication Foundation (WCF) および Windows Workflow Foundation (WF) のサンプルからダウンロードできます 。次に :\WF_WCF_Samples\WF\Application\VisualWorkflowTracking*

4

3 に答える 3

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 を追加します。

アダム これがコードです

  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;
        }
于 2012-07-11T09:12:44.510 に答える
1

追跡参加者を使用して、ワークフローの実行中に変数と引数を抽出できます。

于 2012-07-09T19:29:01.677 に答える
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>

アクティビティが閉じると、このトレースがこの引数を受け取ります

[Arg] 値 = PDC Rocks [Arg] To = PDC Rocks

そして、値が代入されるvarの名前がわかりません

于 2012-07-10T09:29:31.437 に答える