Question

I have created a windows workflow state machine that has custom activities (CodeActivity). These custom activities need to access the database and I have a property which contains the database connection.

At the beginning of each action, I initialize the database context, do some stuff and then dispose the database action. This is currently causing a problem, which I believe boils down to the fact that the same instance of the code activity can be used if an activity is invoked from two separate instances of the workflow concurrently.

For example, let's suppose my activity is called DoSomething and looks like the following:

public class DoSomething : CodeActivity
{
    protected DbContext DbContext { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        using (this.DbContext = CreateMyDatabaseContext())
        {
            DoSomething(this.DbContext);
        }
    }

}

If two instances of the workflow invoke DoSomething() at the same time, then (because the same instance of DoSomething is being used), they will be pointing to the same database context.

But what I want, instead, is to have each invocation of the activity use a new instance of the activity.

If this is not possible, then I understand I will need to remove any instance properties from the activity, and that's an acceptable answer.

But I am wondering if there is another mechanism I can use in which I can have instance properties. For example, is there a property on the workflow which determines how activity objects are created (e.g. separate instance for each workflow)? Or something like that?

Thanks for your help, Eric

Was it helpful?

Solution

Options for using single or multiple instances of workflows depend on how do you host and initialize workflows?

Nonetheless using should not initialize property. Using statement limits life of variable to that block only while property can be used from everywhere.

In general, for Workflows, I would never use non thread-safe objects as properties for Activity. Especially if instance of that object is bound for specific request. Better approach would be to initialize object in one activity (which can be designed to be very flexible and powerful), add it to current ActivityContext and use it from there in next activities.

OTHER TIPS

You can use the Variable<T> type for workflow instance state.

In addition the following types are used for flowing data in and out of workflow instances:

InArgument<T>
OutArgument<T>
InOutArgument<T>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top