我正在尝试捕获名为“arg1”的参数的跟踪 我使用此跟踪配置文件
private MyTrace CreateTrace()
{
string all="*"
MyTrace trace = new MyTrace();
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 }
},
ActivityStateQuery query = new ActivityStateQuery()
new ActivityStateQuery()
{
ActivityName = "*",
States = { ActivityStates.Executing ,ActivityStates.Closed},
Arguments={"arg1"}
}
}
};
return trace;
}
要跟踪的活动:(这很简单arg1 =“value”)
<Activity mc:Ignorable="sap" x:Class="WorkflowConsoleApplication5.Workflow1" 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:s4="clr-namespace:System;assembly=System.ServiceModel"
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:sl="clr-namespace:System.Linq;assembly=System.Core"
xmlns:st="clr-namespace:System.Text;assembly=mscorlib"
xmlns:w="clr-namespace:WorkflowConsoleApplication5"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<x:Members>
<x:Property Name="arg1" Type="InArgument(x:String)" />
</x:Members>
<sap:VirtualizedContainerService.HintSize>654,676</sap:VirtualizedContainerService.HintSize>
<mva:VisualBasic.Settings>Assembly references and imported namespaces for internal implementation</mva:VisualBasic.Settings>
<Flowchart sap:VirtualizedContainerService.HintSize="614,636">
<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,2.5</av:Point>
<av:Size x:Key="ShapeSize">60,75</av:Size>
<av:PointCollection x:Key="ConnectorLocation">300,77.5 300,171</av:PointCollection>
</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,171</av:Point>
<av:Size x:Key="ShapeSize">242,58</av:Size>
<av:PointCollection x:Key="ConnectorLocation">300,229 300,259 290,259 290,299.5</av:PointCollection>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<Assign sap:VirtualizedContainerService.HintSize="242,58">
<Assign.To>
<OutArgument x:TypeArguments="x:String">[arg1]</OutArgument>
</Assign.To>
<Assign.Value>
<InArgument x:TypeArguments="x:String">value</InArgument>
</Assign.Value>
<sap:WorkflowViewStateService.ViewState>
<scg3:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
</Assign>
<FlowStep.Next>
<FlowStep x:Name="__ReferenceID1">
<sap:WorkflowViewStateService.ViewState>
<scg3:Dictionary x:TypeArguments="x:String, x:Object">
<av:Point x:Key="ShapeLocation">184.5,299.5</av:Point>
<av:Size x:Key="ShapeSize">211,61</av:Size>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<WriteLine sap:VirtualizedContainerService.HintSize="211,61" Text="[arg1]">
<sap:WorkflowViewStateService.ViewState>
<scg3:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
</WriteLine>
</FlowStep>
</FlowStep.Next>
</FlowStep>
</Flowchart.StartNode>
<x:Reference>__ReferenceID0</x:Reference>
<x:Reference>__ReferenceID1</x:Reference>
</Flowchart>
</Activity>
public class MyTrace : TrackingParticipant
{
private String participantName = "Mytrace";
protected override void Track(TrackingRecord record, TimeSpan timeout)
{
Console.WriteLine("*{0}+++++++++++++++++++++++++++++++++++++",record.RecordNumber);
Console.Write(String.Format(CultureInfo.InvariantCulture, "{0} emitted trackRecord: {1} Level: {2}, RecordNumber: {3}", participantName, record.GetType().FullName, record.Level, record.RecordNumber));
WorkflowInstanceRecord workflowInstanceRecord = record as WorkflowInstanceRecord;
if (workflowInstanceRecord != null)
{
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
" Workflow InstanceID: {0} Workflow instance state: {1}",
record.InstanceId, workflowInstanceRecord.State));
}
ActivityStateRecord activityStateRecord = record as ActivityStateRecord;
if (activityStateRecord != null)
{
IDictionary<String, object> variables = activityStateRecord.Variables;
IDictionary<string, object> arguments = activityStateRecord.Arguments;
StringBuilder vars = new StringBuilder();
if (variables.Count > 0)
{
vars.AppendLine("\n\tVariables:");
foreach (KeyValuePair<string, object> variable in variables)
{
vars.AppendLine(String.Format(
"\t\tName: {0} Value: {1}", variable.Key, variable.Value));
}
}
StringBuilder args = new StringBuilder();
if (arguments.Count > 0)
{
args.AppendLine("\n\tArguments:");
foreach (KeyValuePair<string, object> arg in arguments)
{
args.AppendLine(String.Format(
"\t\tName: {0} Value: {1}", arg.Key, arg.Value));
}
}
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
" :Activity DisplayName: {0} :ActivityInstanceState: {1} {2} {3}",
activityStateRecord.Activity.Name, activityStateRecord.State,
((variables.Count > 0) ? vars.ToString() : String.Empty),
((arguments.Count > 0) ? args.ToString() : String.Empty)));
}
CustomTrackingRecord customTrackingRecord = record as CustomTrackingRecord;
if ((customTrackingRecord != null) && (customTrackingRecord.Data.Count > 0))
{
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"\n\tUser Data:"));
foreach (string data in customTrackingRecord.Data.Keys)
{
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
" \t\t {0} : {1}", data, customTrackingRecord.Data[data]));
}
}
Console.WriteLine();
}
}
当我执行活动(Workflow1)时,我会收到此跟踪输出:
*0+++++++++++++++++++++++++++++++++++++
TrackingParticipant emitted trackRecord: System.Activities.Tracking.WorkflowInstanceRecord Level: Info, RecordNumber: 0 Workflow InstanceID: a5b135ce-03d0-40ea-a491-15ff01030e05 Workflow instance state: Starte
*1+++++++++++++++++++++++++++++++++++++
TrackingParticipant emitted trackRecord: System.Activities.Tracking.ActivityStateRecord Level: Info, RecordNumber: 1 :Activity DisplayName: Workflow1 :ActivityInstanceState: Executing
Arguments:
Name: arg1 Value: HOLA
*2+++++++++++++++++++++++++++++++++++++
TrackingParticipant emitted trackRecord: System.Activities.Tracking.ActivityStateRecord Level: Info, RecordNumber: 2 :Activity DisplayName: Flowchart :ActivityInstanceState: Executing
*3+++++++++++++++++++++++++++++++++++++
TrackingParticipant emitted trackRecord: System.Activities.Tracking.ActivityStateRecord Level: Info, RecordNumber: 3 :Activity DisplayName: Assign :ActivityInstanceState: Executing
*4+++++++++++++++++++++++++++++++++++++
TrackingParticipant emitted trackRecord: System.Activities.Tracking.ActivityStateRecord Level: Info, RecordNumber: 4 :Activity DisplayName: Assign :ActivityInstanceState: Closed
value
*5+++++++++++++++++++++++++++++++++++++
TrackingParticipant emitted trackRecord: System.Activities.Tracking.ActivityStateRecord Level: Info, RecordNumber: 5 :Activity DisplayName: WriteLine :ActivityInstanceState: Executing
*6+++++++++++++++++++++++++++++++++++++
TrackingParticipant emitted trackRecord: System.Activities.Tracking.ActivityStateRecord Level: Info, RecordNumber: 6 :Activity DisplayName: WriteLine :ActivityInstanceState: Closed
*7+++++++++++++++++++++++++++++++++++++
TrackingParticipant emitted trackRecord: System.Activities.Tracking.ActivityStateRecord Level: Info, RecordNumber: 7 :Activity DisplayName: Flowchart :ActivityInstanceState: Closed
*8+++++++++++++++++++++++++++++++++++++
TrackingParticipant emitted trackRecord: System.Activities.Tracking.ActivityStateRecord Level: Info, RecordNumber: 8 :Activity DisplayName: Workflow1 :ActivityInstanceState: Closed
Arguments:
Name: arg1 Value: value
*9+++++++++++++++++++++++++++++++++++++
为什么参数(arg1)仅在Workflow1关闭时发生更改? 什么事情发生在assing arg1 =“value”?我认为必须通知参数已更改
答案 0 :(得分:1)
使用Ron Jacobs创建的跟踪参与者。在活动运行后查询非常容易,因为它具有结构化结果,并且您将能够在每个阶段实际获取该参数。它实际上为参与者使用Microsoft.Activities.UnitTesting框架。该参与者实际上也可以同时跟踪子工作流程!
以下是一些博客文章,Ron解释了如何使用它。
http://blogs.msdn.com/b/rjacobs/archive/2011/01/13/wf4-how-tracking-helped-me-write-a-unit-test.aspx
http://blogs.msdn.com/b/rjacobs/archive/2011/05/26/tracking-child-workflow-with-invokeworkflow.aspx
http://blogs.msdn.com/b/rjacobs/archive/2012/06/18/what-state-is-my-statemachine-in.aspx
我正在对此进行编辑,以澄清如果您必须更频繁地更新,则需要跟踪变量并不参数。因此,将变量的值设置为参数的值,然后如果在离开工作流之前需要,请将参数的值设置为变量的值,但在工作流结束时设置InArgument实际上是无效果,因为没有人会使用它(至少我假设)。