WorkflowRuntime events are missing when using an indexer! Bug or Feature?

Hello,

we are getting some strange behavior from the WorkflowRuntime when using an C# indexer within a SequentialWorklfowActivity, the events like WorkflowCompleted are not being fired anymore.

Here is the scenario/code:

namespace WorkflowConsoleApplication3 {

public sealed partial class Workflow1 : SequentialWorkflowActivity {

public Workflow1() {
InitializeComponent();
Console.WriteLine("MySequentialWorkflow ctor");
Variables
= new Variable2[] { new Variable2("WorkplaceName", "", false, ""),
new Variable2("UserName", "", false, ""), };
}

[Description("Variables for this workflow")]
public Variable2[] Variables {
get { return variables; }
set { variables = value; }
}

private Variable2[] variables;

private void codeActivity1_ExecuteCode(object sender, EventArgs e) {
Console.WriteLine(this["FooVar"]);
}

// INDEXER
public
string this[string Name] {
get {
Variable2 v = FindVar(Name);
if(v != null)
return v.Value;

return "";
}

set {
Variable2 v = FindVar(Name);
if(v != null)
v
.Value = value;
}
}

public Variable2 FindVar(string Name) {
foreach(Variable2 v in Variables)
if(v._Name == Name) return v;
return null;
}

public string GetVar(string Name) {
Variable2 v = FindVar(Name);
if(v == null) return " " + Name + " unknown ";

return v.Value;
}

public bool SetVar(string Name, string Value)’{
Variable2 v = FindVar(Name);
if(v == null) return false;
v
.Value = Value;
return true;
}
}

[Serializable]
public class Variable2 {
public Variable2() { }
public Variable2(string aName, string aValue, bool bReqOnCreation, string aDescription) {
name
= aName;
val
= aValue;
description
= aDescription;
reqOnCreation
= bReqOnCreation;
}

// There a number of properties here to get the values
}

The main program (a console app) creates the WorkflowRuntime as usual and subscribes to the events, like so:

using(WorkflowRuntime workflowRuntime = new WorkflowRuntime()) {
AutoResetEvent waitHandle = new AutoResetEvent(false);
workflowRuntime
.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {
Console.WriteLine("WorkflowCompleted event received.");
waitHandle
.Set();
};

workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e){
Console.WriteLine(e.Exception.Message);
waitHandle
.Set();
};

From the moment on where I use an indexer like illustrated above these two WorkflowRuntime events are not fired anymore! Is this a known limitation/feature/bug When using a "string GetVariable(string name)" and a "void SetVariable(string name, string value)" then the events are delivered as expected! But what makes the explicit method approach different from the indexer approach, if one considers that the C# compiler generates the same kind of methods!

It is very easy to reproduce this behavior, just copy and paste the Workflow1 code from above including the definition for Variable2 and add the fields/properties to the Variable2 class in order to access the values. Have a console workflow test program and use the above illustrated subscritpion code.

So please come back whith some information on that topic!

Regards,
Andy



Answer this question

WorkflowRuntime events are missing when using an indexer! Bug or Feature?

  • StefanKZVB

    Hi SonaliC,

    where do you see this exception happening I don't get this exception at all!
    Do you use some special build or workflow engine trace facilities
    Well, since I don't get this exception I can't tell you if we are on the same spot or not
    But obviously there is some trouble using an indexer at the root activity level!

    Please come back to me with concrete information whether or not this is a bug and provide me with some workaround scenarios.

    Regards,
    Andy


  • Big Andy 78

    Hi Andy,

    Trace file is just another trouble shooting mechanism.You will see the same exception in the trace file.

    For your scenario, workaround is to create a seperate class instead of having an indexer on the root activity.
    Also I will recommend to initialize any variables in the "Initialized" handler of the workflow and not in the constructor.

    I have created a VariableCollection class and used it in the workflow. Can you try this on your system and see if it works

    public sealed partial class Workflow2: SequentialWorkflowActivity

    {

    private Variable2Collection list;

    public Workflow2()

    {

    InitializeComponent();

    }

    private void codeActivity1_ExecuteCode(object sender, EventArgs e)

    {

    Console.WriteLine(list["FooVar"]);

    }

    //This is the handler for the "Initialized" event on the root activity

    private void WorkflowInit(object sender, EventArgs e)

    {

    list = new Variable2Collection(new Variable2[]

    { new Variable2("WorkplaceName", "", false, ""),

    new Variable2("UserName", "", false, "")

    }

    );

    }

    }

    public class Variable2Collection

    {

    private Variable2[] Variables;

    public Variable2Collection()

    {

    Variables = new Variable2[10];

    }

    public Variable2Collection(Variable2[] list)

    {

    Variables = list;

    }

    public string this[string name]

    {

    get

    {

    Variable2 v = FindVar(name);

    if (v != null)

    return v.Value;

    return "";

    }

    set

    {

    Variable2 v = FindVar(name);

    if (v != null)

    v.Value = value;

    }

    }

    public Variable2 FindVar(string Name)

    {

    foreach (Variable2 v in Variables)

    if (v._Name == Name) return v;

    return null;

    }

    public string GetVar(string Name)

    {

    Variable2 v = FindVar(Name);

    if (v == null) return " " + Name + " unknown ";

    return v.Value;

    }

    public bool SetVar(string Name, string Value)

    {

    Variable2 v = FindVar(Name);

    if (v == null) return false;

    v.Value = Value;

    return true;

    }

    }

    Thanks,
    Sonali



  • Sianspheric

    Hi Sonali,

    first of all, thanks for your efforts!

    I tried your proposal (workaround) and it worked now!
    But tell me, did I find a feature (bug) in the RTM of WF Or is this behavior per design

    Your hint with the Activity.Initialize is OK, I understand that, but what if these variables are being defined from within the workflow designer or even a XOML file I have a MySequentialWorkflow type derived from SequentialWorkflowActivity where the VariableCollection is now a field and I still have the Variables[] so that I can work on the designer and set /define the variables each at the time. In the setter/getter of the Variables property I then delegate to the VariableCollection. What solution would you suggest in my described scenario where the variables are defined in the designer/XOML Looking forward for your ideas on that subject!

    Best regards,
    Andy


  • narasiman_jayachandran_2b5374

    Andy, workflowruntime is throwing ServicesExceptionNothandled exception with message "Parameter count mismatch" and that is why you don't see completed event being fired. Host is hanging after this because you are not subscribing to this event and autoreset event is not released. I am investigating the cause of this exception.



  • Euclidez

    Hi Andy,

    I am using 4203.2 build on Win 2003. To make sure we are on same page, can you tell me which build you are using

    Add the following lines to your program.cs to get the exception.

    workflowRuntime.ServicesExceptionNotHandled += delegate(object sender, ServicesExceptionNotHandledEventArgs e)
                    {
                        Console.WriteLine(e.Exception.Message);
                        waitHandle.Set();
                    };

    You can also enable trace by adding an app.config file to your workflow solution. This will log trace in WFTrace.log file.

    < xml version="1.0" encoding="utf-8" >

    <configuration>

    <system.diagnostics>

    <switches>

    <add name="System.Workflow LogToTraceListeners" value="1" />

    <add name="System.Workflow.Runtime.Hosting" value="All" />

    <add name="System.Workflow.Runtime" value="All" />

    <add name="System.Workflow.Runtime.Tracking" value="All" />

    <add name="System.Workflow.Activities" value="All" />

    </switches>

    <trace autoflush="true" indentsize="4">

    <listeners>

    <add name="myListener"

    type="System.Diagnostics.TextWriterTraceListener"

    initializeData="WFTrace.log" />

    </listeners>

    </trace>

    </system.diagnostics>

    </configuration>

    There seems some problem in using the indexer in root activity. I will get back to you with more information as soon as possible

    -Sonali



  • jmurray_mi

    Hi SonaliC,

    I'm using the same build as you (the RTM version of the .NET FX 3.0 that is) on a Windows Vista Ultimate RTM box.

    I added the ServicesExceptionNotHandled event handler and I'm getting now the same exception as you described in your previsouly post. I also enabled the tracing facilities in the app.config and can see the traces. Anything particular that I should see in the trace file

    Regards,
    Andy


  • WorkflowRuntime events are missing when using an indexer! Bug or Feature?