locked
CodeActivity Class Variable Keep data between instances RRS feed

  • Question

  • Hi All,

    Assuming CodeActivity1 class with class level variable MyVar, that increase by 1 each time Execute is called, for example count how many time the certain activity was used in a certain workflow instance. (this is not the real use case but rather a pseudo one to keep thing simple, so please no suggestion regarding how to solve the particular presented problem)

     

        public sealed class CodeActivity1 : CodeActivity
        {
            // Define an activity input argument of type string
            public OutArgument<int> Val { get; set; }
    
    
            int MyVar = 0;
    
            // If your activity returns a value, derive from CodeActivity<TResult>
            // and return the value from the Execute method.
            protected override void Execute(CodeActivityContext context)
            {
                // Obtain the runtime value of the Text input argument
                ++MyVar;
                context.SetValue( Val ,MyVar);
    
                
            }
        }
    

     

    now when we run a flow containing this activity in the following way

     

                 for(int i=0;i<10;++i)
                 {
                     Activity Act = new Workflow1();
                     WorkflowApplication wfapp = new WorkflowApplication(Act);
    
    
                     wfapp.BeginRun((X)=>{},null);
    
                 };
    


    everything is working fine and we get correctly the amount of usage in CodeActivity1

    When however we try to cache the flow, in order to minimize initialization time

    like this

                 Activity Act = new Workflow1();
                 WorkflowInspectionServices.CacheMetadata(Act);
    
    
                 for(int i=0;i<10;++i)
                 {
                     WorkflowApplication wfapp = new WorkflowApplication(Act);
    
                     wfapp.BeginRun((X)=>{},null);
    
    
                 };
    

    instead of each instance start with MyVar=0;

    They all share the same MyVar and increasing one other value

    It seems that class level variable is shared among instances when using a single-ton instance as a detention for the workflowApplication

    Anyone can Approve or Disapprove?

    Is the an easy solution without involving the Context Object and still benefiting from the MetaDataCaching?

    Thanks,

    Avi

     

     

     

     

     

    Sunday, October 23, 2011 12:24 PM

Answers

  • The idea was to find a way to use a state codeactivity, that the state reset between execution of different workflow instance.

    The solution suggested by Ron is great, very useful however do require to use NativyActivity, making it even more complicated if you need to use an Async activity which will then one will need to use bookmarks, more ever the Variable<T> do rest between iteration, meaning each execution of the activity rest the state, which wasn't the intention.

    I believe that a more true soultion will be, the use of extension that is set to the workflowapplicaiton instance and therfore maintane state.


    • Edited by Avi Kadosh Monday, October 31, 2011 4:46 PM
    • Marked as answer by Avi Kadosh Monday, October 31, 2011 4:46 PM
    Sunday, October 30, 2011 2:18 PM

All replies

  • Ok, Some real time example
    One of Microsoft WF Sample is the CSWF4CustomSequenceActivity,
    in the MySequenceActivity.cs one can find
     
    int activityCounter = 0;
    

    now if one change the Main() in the Program.CS to
                Activity Act =  new Workflow1();
    
               
                for(int i =0;i<3;++i)
                {
                    System.Threading.ManualResetEvent MRE = new System.Threading.ManualResetEvent(false);
                    WorkflowApplication wfapp = new WorkflowApplication(Act);
    
                    wfapp.Completed = (x) => { MRE.Set(); };
    
                    
                    wfapp.Run();
    
                    MRE.WaitOne();
    
                }
    
    

    So instead of running 3 times, and printing 1,2,3,1,2,3,1,2,3 the prgoram will only print 1,2,3
     
    This of course could easly be avoided by using
     
    Variable<int> activityCounter;

    _

    But this solution will not solve the first issue 

    Sunday, October 23, 2011 5:57 PM
  • The solution is to use a Variable<T> that is registered with the context as an Implementation Variable.  I posted a sample of this

    Windows Workflow Foundation (WF4) - Activity State Sample

     


    Sr. Program Manager, Windows Azure Platform Team(WF) http://blogs.msdn.com/rjacobs http://www.twitter.com/ronljacobs
    • Marked as answer by LeoTang Sunday, October 30, 2011 1:25 PM
    • Unmarked as answer by Avi Kadosh Sunday, October 30, 2011 1:34 PM
    Monday, October 24, 2011 3:45 PM
  • The idea was to find a way to use a state codeactivity, that the state reset between execution of different workflow instance.

    The solution suggested by Ron is great, very useful however do require to use NativyActivity, making it even more complicated if you need to use an Async activity which will then one will need to use bookmarks, more ever the Variable<T> do rest between iteration, meaning each execution of the activity rest the state, which wasn't the intention.

    I believe that a more true soultion will be, the use of extension that is set to the workflowapplicaiton instance and therfore maintane state.


    • Edited by Avi Kadosh Monday, October 31, 2011 4:46 PM
    • Marked as answer by Avi Kadosh Monday, October 31, 2011 4:46 PM
    Sunday, October 30, 2011 2:18 PM