locked
How to read the OutArument of the inner activity RRS feed

  • Question

  • public
     sealed
     class
    
    
    
     CustomActivity : CodeActivity<int
    >
     {
            // Define an activity input argument of type string
    
          
            // If your activity returns a value, derive from CodeActivity<TResult>
    
    
            // and return the value from the Execute method.
    
    
    
            protected
     override
     int
     Execute(CodeActivityContext context)
           {           
             return
     100;
           }
     }
    

    Sequence s = new
    
    
    
     Sequence()
      {
            Activities =
            {
               new
    
     CustomActivity()
            }
     }
    WorkflowInvoker.Invoke(s);
    Is there any way to get the return value of CustomActivity after my WorkflowInvoker.Invoke() returns?
    Thursday, December 3, 2009 9:13 AM

Answers

  • Hi Cantry,

    Are you trying to use the value returned by your custom activity inside your sequence? If this is the case, you will need to use a variable to do the binding. The code below shows how to do this using your custom activity.

    var result = new Variable<int>();
    
    Activity wf = new Sequence 
    {
        Variables = { result },
        Activities = 
        {
            new CustomActivity
            {
                Result = result
            },
            new WriteLine
            {
                Text = new InArgument<string>(c => result.Get(c).ToString())
            }
        }
    };
    
    WorkflowInvoker.Invoke(wf);

    If what you want is to get the result, WorkflowInvoker returns an IDictionary<string, object> with all the OutArguments of the activity that has been executed. In your case, if you just execute your custom code activity (CodeActivity<int>, WorkflowInvoker will just return and int value:

    int result = WorkflowInvoker.Invoke(new CustomActivity());
    Console.WriteLine(result);       

    Finally, if your activity returns more than one value you will receive an instance of an IDictionary<string, object> with the values:

    public sealed class SayHello : CodeActivity
    {
        public OutArgument<string> Word1 { get; set; }
        public OutArgument<string> Word2 { get; set; }
    
        protected override void Execute(CodeActivityContext context)
        {
            this.Word1.Set(context, "Hello");
            this.Word2.Set(context, "World");
        }
    }
    
    // executing the activity and using the values
    IDictionary<string, object> results = WorkflowInvoker.Invoke(new SayHello());
    Console.WriteLine(results["Word1"]);
    Console.WriteLine(results["Word2"]);

    Leon Welicki,
    Program Manager, WF
    • Proposed as answer by Leon Welicki - MSFT Friday, December 4, 2009 4:20 AM
    • Marked as answer by cantry Tuesday, May 24, 2011 10:27 AM
    Friday, December 4, 2009 4:19 AM

All replies

  • Hi Cantry,

    We do not support get return value of inner activities. You can only pass input or get output from the root activity, using the below function of WorkflowInvoker:

    //

     

     

    // Summary:

     

     

    // Invokes a workflow synchronously using the specified workflow definition

     

     

    // and System.Collections.Generic.IDictionary<TKey,TValue> of input parameters.

     

     

    //

     

     

    // Parameters:

     

     

    // workflow:

     

     

    // The workflow definition of the workflow to invoke.

     

     

    //

     

     

    // inputs:

     

     

    // The dictionary of input parameters to the workflow, keyed by argument name.

     

     

    //

     

     

    // Returns:

     

     

    // A dictionary of the root activity’s System.Activities.OutArgument and System.Activities.InOutArgument

     

     

    // values keyed by argument name that represent the outputs of the workflow.

     

     

    public static IDictionary<string, object> Invoke(Activity workflow, IDictionary<string, object> inputs);

    So for your example, what you can do is to design an out argument in root sequence activity to be the value of your expected return value (i.e. the return value from your inner activity), and then get it via the Invoke function.

    Hope it helps.

    Regards,
    Panda

    This posting is provided "AS IS" and confers no rights or warranties.

    • Proposed as answer by Panda Wang Thursday, December 3, 2009 10:05 AM
    Thursday, December 3, 2009 10:03 AM
  • Hi,
       Thanks for your reply.   Your reply looks convincing to me, but would it be possible for you to post the code snippet.

    Thanks in advance for your help
    Thursday, December 3, 2009 11:20 AM
  • Panda Wang: So for your example, what you can do is to design an out argument in root sequence activity to be the value of your expected return value (i.e. the return value from your inner activity), and then get it via the Invoke function.

    cantry:Your reply looks convincing to me, but would it be possible for you to post the code snippet.

    Code Snippet:
    http://msdn.microsoft.com/en-us/library/ee342461.aspx

    Please check Figure 14 in the above link.
    Friday, December 4, 2009 3:23 AM
  • Hi Cantry,

    Are you trying to use the value returned by your custom activity inside your sequence? If this is the case, you will need to use a variable to do the binding. The code below shows how to do this using your custom activity.

    var result = new Variable<int>();
    
    Activity wf = new Sequence 
    {
        Variables = { result },
        Activities = 
        {
            new CustomActivity
            {
                Result = result
            },
            new WriteLine
            {
                Text = new InArgument<string>(c => result.Get(c).ToString())
            }
        }
    };
    
    WorkflowInvoker.Invoke(wf);

    If what you want is to get the result, WorkflowInvoker returns an IDictionary<string, object> with all the OutArguments of the activity that has been executed. In your case, if you just execute your custom code activity (CodeActivity<int>, WorkflowInvoker will just return and int value:

    int result = WorkflowInvoker.Invoke(new CustomActivity());
    Console.WriteLine(result);       

    Finally, if your activity returns more than one value you will receive an instance of an IDictionary<string, object> with the values:

    public sealed class SayHello : CodeActivity
    {
        public OutArgument<string> Word1 { get; set; }
        public OutArgument<string> Word2 { get; set; }
    
        protected override void Execute(CodeActivityContext context)
        {
            this.Word1.Set(context, "Hello");
            this.Word2.Set(context, "World");
        }
    }
    
    // executing the activity and using the values
    IDictionary<string, object> results = WorkflowInvoker.Invoke(new SayHello());
    Console.WriteLine(results["Word1"]);
    Console.WriteLine(results["Word2"]);

    Leon Welicki,
    Program Manager, WF
    • Proposed as answer by Leon Welicki - MSFT Friday, December 4, 2009 4:20 AM
    • Marked as answer by cantry Tuesday, May 24, 2011 10:27 AM
    Friday, December 4, 2009 4:19 AM