João Ricardo Pereira

Hi there

I'm trying to extract the initial parameters of a persisted workflow for comparison purposes, without the need to instantiate him.

I'll try to explain it...
I have a workflow that describes the life cycle of a customer inside a business home.
When the customer arrive, they are admitted in the reception where a few personal information is gathered.
A workflow is created for every one that is admitted. They pass through 3 different steps and talk to 3 different end users of the application until the workflow is finished.
For every step I want the end user to have a display list of customers in list for that step by order they arrived.
Throught SQLTrackingService I manage to track in what activity the workflow is persisted, and show to the end user only the persons that are waiting for him (I guess I figured this out... still needs testing).

My problem comes now...

My application is a internet ASP.NET web application that is used in various business home's in different points of the country. Each one has a different ID that is passed to the workflow at the beginning as a Dictionary value.
So when I query the persisted workflow I can get the activity that is waiting to be executed, but I need to know where the person is!

- Is there any way to get the input Dictionary of the workflow when he is persisted without instanciate it (As this is a web app the workflow runtime and instance doesn't persist from step to step...)

- Is there any way to access the args passed to the workflow in a Dictionary format in a HandleExternalEventActivity (For now I don't need to access this, but I think it will be handy in the future...)

If anyone can help in this I appreciate it in advance... Thanks


Cheers
Joao Pereira



Re: Windows Workflow Foundation Extract values from persisted workflow without instanciate it

Tom Lake - MSFT

By passing a Dictionary to the workflow do you mean like the following:

Dictionary<string, object> parameters = new Dictionary<string, object>();

parameters.Add("ID", 123456);

WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(Workflow1), parameters);

Each item added to the dictionary must correspond to a property on the workflow. Because of this it is accesible to any activity in the workflow, like the following for the HandleExternalEventActivity¡¯s Invoked handler:

private void handleExternalEventActivity1_Invoked(object sender, ExternalDataEventArgs e)

{

Console.WriteLine(this.ID);

}

To get the value of a variable / property in a workflow while it is running, without sending a message to it, you need to use a tracking profile. Take a look at the sample here, specifically at the GetOrderNumber method in Order.aspx.cs.






Re: Windows Workflow Foundation Extract values from persisted workflow without instanciate it

Joao Ricardo Pereira

Yes. Passing a Dictionary to the workflow like the example you wrote was exactly what I meant.

I had already seen the sample you point me, but I didn't paid much attention to it...

Yesterday I looked at it carefully and I was able to query the Track DB and return the Args parameters I inserted in the HandleExternalEvent.

But what I really wanted was to query the Track DB to get the initial values inserted in the workflow that wasn't passed through a HandleExternalEvent event.

My workflow was like this:
CodeActivity
HandleExternalActivity
CodeActivity
HandleExternalActivity
CodeActivity
HandleExternalActivity
CodeActivity

I used to start it this way:

// Create WFRuntime of type Distribution
BaseClass baseClass = new BaseClass();
this.workflowRuntime = baseClass.createWFRuntime(this);

// Instanciate events on Runtime
this.InstanciateEvents(workflowRuntime);

// Create Values Dictionary
Dictionary<string, object> properties = new Dictionary<string, object>();
properties.Add("FromProviderID", fromProviderID);
properties.Add("ToProviderID", toProviderID);
properties.Add("ItemsList", itemsList);

// Define type of workflow
Type type = typeof(Distribution);

//Create WFInstance from WFRuntime, WFGuid, WFType, WFDictionary
this.workflowInstance = this.createWFInstance(workflowRuntime, guid, type, properties);

if (wfGuid.Equals(Guid.Empty) || wfGuid.Equals(null))
{
workflowInstance = wfRuntime.CreateWorkflow(type, properties);
}
else
{
wfRuntime.StartRuntime();
wfRuntime.GetWorkflow(wfGuid);
workflowInstance = wfRuntime.GetWorkflow(wfGuid);
}

if (guid.Equals(Guid.Empty))
this.workflowInstance.Start();
else
this.workflowInstance.Resume();

(Some of this code was in separated classes and I put it all together just to give an idea of what I'm trying to do...)

Now I added a HandleExternalActivity at the beginning and started the workflow without sending any parameters when creating and starting the workflow. In the method I start the workflow I raise the first event that is handled by the HandleExternalEvent and pass the properties Dictionary I used to pass at the beginning in the event. Like this I'm able to track the information I need only by querying the DB.

The first approach I used seems simpler to me. But it was unable to fulfil my needs.
Was it a wrong approach or it can be done in any other way



Thanks for your help






Re: Windows Workflow Foundation Extract values from persisted workflow without instanciate it

wirwin

Rather than trying to force the Tracking database to do something it wasn't really designed for, perhaps it would be better to create a separate database which holds the information you need (the contents of the Dictionary), using the workflow ID as a key. You can easily query this database to get lists of customers (workflows) that each of your users is responsible for, etc.

When your workflow starts the first thing it would do would be to save the values of interest into this database.  When the workflow ends you could delete them (or mark them in some way to indicate they are no longer active, or whatever is useful).

If you find the need later to store more application specific information about each workflow you can just add more columns/tables to your own database.

It seems better to treat the WF Tracking (and Persistence) databases as private storage used by the WF runtime, and handle any application-specific information in a separate database.




Re: Windows Workflow Foundation Extract values from persisted workflow without instanciate it

Joao Ricardo Pereira

I agree with you... And it was my first approach.
But then... We won¡¯t be taking full advantage of the workflows!

The persistence database is used by the workflow runtime, but the tracking database is useless to the workflow itself.
I believe tracking is more likely a way to control the flow of information.

The best uses I see for tracking is debugging the workflows, audit the application and control the flow and state of the workflow.


If you want to have a complete audit of the system and to control the flow and state you need to track the input values also.
If tracking is enabled as is considered an option, it¡¯s not one or two more parameters to track that will be a bad use of it.

I started the application and created in the application DB some boolean fields marking the state of workflow. If it his in 2nd activity, then it is waiting for departure, if it is in 4th activity is waiting to arrive...
But I believe that we can do a better approach by querying the tracking DB for values and states instead of record information in various DB tables and query it in every step.
This way I query the Tracking DB and only update the application DB at the end of workflow. It works like a "rollback" if it doesn¡¯t reach the end...

I¡¯ve also considered the performance part¡­ and I didn¡¯t found anything to read regarding this¡­
TrackingQuery the DB queries all tracked activities and not only the persisted workflows activities¡­ Is there a way to make this selection

If anyone can enlighten me in this, I would appreciate it.






Re: Windows Workflow Foundation Extract values from persisted workflow without instanciate it

Tom Lake - MSFT

To use tracking to retrieve the first value of the workflow property, first create a tracking profile like CreateAndInsertTrackingProfile method in the Global.asax file of the sample. The following is the important part:

System.Workflow.Runtime.Tracking.WorkflowDataTrackingExtract workflowDataTrackingExtract = new System.Workflow.Runtime.Tracking.WorkflowDataTrackingExtract();

workflowDataTrackingExtract.Member = "Param"; // use actual property name

trackPoint.Extracts.Add(workflowDataTrackingExtract);

Add one for each property you want to track. To retreive the value look at the code in the GetOrderNumber method of Order.aspx.cs. Instead of using (ActivityTrackingRecord)records[records.Count - 1] you will always want the first value so use (ActivityTrackingRecord)records[0].






Re: Windows Workflow Foundation Extract values from persisted workflow without instanciate it

Bharat Bhushan

Hi -

You need to change your approch don;t query that what is the state of workflow instanse, query what can be done at that state (what events that wotokflow can listen at that time). By listening u can come to know what can be done.

In this way ur workfow will more flexible don't need to change application if flow is getting change.

(Example if now in 1 state T1 can be done/ after changes in 1 state T1 and T2 can be done). no need to change application.

When any customer come save instance id along with his record.