locked
How to get the path taken by a FlowDecision activity? RRS feed

  • Question

  • Hello,

    I have a custom TrackingParticipant and I want to trace which flow line is taken after a FlowDecision activity is executed. This is my tracking profile:

                this.TrackingProfile = new TrackingProfile()
                    {
                        Name = "WorkflowTrackingProfile",
                        Queries =
                        {
                            new CustomTrackingQuery()
                                {
                                    Name = WorkflowTrackingParticipant.All,
                                    ActivityName = WorkflowTrackingParticipant.All
                                },
                            new WorkflowInstanceQuery()
                                {
                                    // Limit workflow instance tracking records for started and completed workflow states
                                    States = { WorkflowInstanceStates.Started, WorkflowInstanceStates.Completed },
                                },
                            new ActivityStateQuery()
                                {
                                    // Subscribe for track records from all activities for all states
                                    ActivityName = WorkflowTrackingParticipant.All,
                                    States = { WorkflowTrackingParticipant.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 =
                                    {                               
                                        { WorkflowTrackingParticipant.All }  
                                    }
                                }
                        }
                    };

    Currently, I'm getting VisualBasicValue<Boolean> activities in ActivityStateRecord records.

    Thanks,

    Carlos

    Friday, January 14, 2011 4:23 AM

Answers

  • Hi Carlos, 

    well actually the right way to obtain the "Result" argument value from the TrackingPartecipant is not using hthe ActivityContext. In fact, some TrackingRecord(s) contain argument VALUES (not expressions), so they are already VALUED. The "Result" is one of them on the ActivityState (State=Closed, ... if I am not wrong) tracking record.

    I am using this syntax to cycle through paraemter values and store thm on db:

        If TypeOf TrackingRecord Is ActivityStateRecord Then
          With DirectCast(TrackingRecord, ActivityStateRecord)
            If .Arguments.Count > 0 Then
              ' add arguments.
              For Each traceArg As KeyValuePair(Of String, Object) In .Arguments
                Dim newArg As New TraceRecordInfoArg()
    
                newArg.Name = traceArg.Key
                newArg.Value = String.Format("{0}", traceArg.Value)
    
                ' The following is a hack. We use Closed state to detect possible output values... and mark as output values.
                If .State = ActivityStates.Closed Then
                  ' when state = close then we read output args
                  Dim sameInArg As TraceRecordInfoArg = SourceRecordInfo.InputArguments(traceArg.Key)
    
                  ' when same input arg does NOT exist, OR the otuput value CHANGED:
                  If sameInArg Is Nothing OrElse sameInArg.Value <> newArg.Value Then
                    SourceRecordInfo.OutputArguments(traceArg.Key) = newArg
                  End If
                Else
                  ' when state is NOT closed, we have input args.
                  SourceRecordInfo.InputArguments(traceArg.Key) = newArg
                End If
              Next
            End If
          End With
    

    HTH,
    Cheers


    Adriano
    • Marked as answer by ca7l0s Monday, January 17, 2011 8:31 AM
    Monday, January 17, 2011 8:02 AM

All replies

  • Hi Carlos, 

    you may want to use WorkflowInspectionServices as described here to gain access tot he underlying Activity definition:

    http://adrianot75.wordpress.com/2010/12/30/wf4-how-to-get-activity-from-trackingpartecipant/

    So that you are able to trace both the condition and the Result (you find them on the in/out argumetns from the ActivityStateRecord).

    Hope it helps,

    Cheers


    Adriano
    Friday, January 14, 2011 8:54 AM
  • Thanks Adriano! That showed me how to get the activity object with the Result property. However, I still don't know to use the Result argument since it requires an ActivityContext instance. I'm not sure if a tracking participant is supposed to or how it could have access to the current ActivityContext.

    ---

    Carlos
    Monday, January 17, 2011 5:18 AM
  • Hi Carlos, 

    well actually the right way to obtain the "Result" argument value from the TrackingPartecipant is not using hthe ActivityContext. In fact, some TrackingRecord(s) contain argument VALUES (not expressions), so they are already VALUED. The "Result" is one of them on the ActivityState (State=Closed, ... if I am not wrong) tracking record.

    I am using this syntax to cycle through paraemter values and store thm on db:

        If TypeOf TrackingRecord Is ActivityStateRecord Then
          With DirectCast(TrackingRecord, ActivityStateRecord)
            If .Arguments.Count > 0 Then
              ' add arguments.
              For Each traceArg As KeyValuePair(Of String, Object) In .Arguments
                Dim newArg As New TraceRecordInfoArg()
    
                newArg.Name = traceArg.Key
                newArg.Value = String.Format("{0}", traceArg.Value)
    
                ' The following is a hack. We use Closed state to detect possible output values... and mark as output values.
                If .State = ActivityStates.Closed Then
                  ' when state = close then we read output args
                  Dim sameInArg As TraceRecordInfoArg = SourceRecordInfo.InputArguments(traceArg.Key)
    
                  ' when same input arg does NOT exist, OR the otuput value CHANGED:
                  If sameInArg Is Nothing OrElse sameInArg.Value <> newArg.Value Then
                    SourceRecordInfo.OutputArguments(traceArg.Key) = newArg
                  End If
                Else
                  ' when state is NOT closed, we have input args.
                  SourceRecordInfo.InputArguments(traceArg.Key) = newArg
                End If
              Next
            End If
          End With
    

    HTH,
    Cheers


    Adriano
    • Marked as answer by ca7l0s Monday, January 17, 2011 8:31 AM
    Monday, January 17, 2011 8:02 AM
  • Thanks Adriano!

    I'm getting the correct results now. I ignored all the other states except Executing sometime after posting this question. I didn't notice that the Result argument is included in the Closed state.

    But I guess the path labels as seen in the designer are lost during deserialization. They're not really part of the FlowDecision class. Well, the business people will have to do with either a TRUE or FALSE label then.

    Thanks again!

    ---

    Carlos

    Monday, January 17, 2011 8:30 AM
  • Yes, I know what I mean. 

    The FlowDecision activity is really different than normal activities regarding how they behave on the Tracking and Debugger view/extensions.

    I already asked MS to improve them I am quite sure we get this stuff solved in the vNext of the framework,

    HTH,

    Cheers


    Adriano
    Monday, January 17, 2011 8:34 AM