Answered by:
"Invoke Workflow Synchronously" sample question

Question
-
Hi,
I found strange behaviour in Jon Flanders' sample:
http://www.masteringbiztalk.com/blogs/jon/PermaLink,guid,7be9fb53-0ddf-4633-b358-01c3e9999088.aspx
This is a nice sample, showing how to invoke workflow synchronously. During experimenting, I found the strange behaviour though. I will describe a sample and how to reproduce a problem.
- Lets create workflow, which consists of the only code activity, and code activity handler makes the only operation: Thread.Sleep(5000), i.e. sleeping for 5 seconds.
- Then let's create workflow which calls above created workflow, using sample from the reference.
- Create a host and add there persistence service and local service from the sample above.
Run workflow. It runs, calls the callee and finishes. So far so good.
Run workflow and immediately shutdown the host (or stop runtime). Runtime will be stopped after 5 seconds delay, which is fine. Both workflows will be passivated at this moment. So far so good. When host is started again, workflows are loaded, the callee finalizes, but the caller waits indefinitely.
I found that the reason is that there is no report that callee completed and as a result, item is not enqueued and caller is not closed, staying in memory forever.
Is there a way to fix the sample or maybe I am doing something wrong?
Thanks,
Konstantin.
Saturday, June 2, 2007 3:13 PM
Answers
-
Yep - that would be a bug. I'll have to figure out how to make it work in light of persistence - shoudl have that of that up front - but part of the sample is about the designer as well (not just the sync call workflow).
Likely I'll put a DependencyProperty inside of the called workflow and then also have the service subscribe to the WorkflowLoaded event.
Sunday, June 3, 2007 3:48 AM
All replies
-
Oh, I got the source of the problem. Local service subscribes to Completed and Terminated events on start of callee workflow. When runtime stops, this subscribtion is lost, and item is not enqueued back to caller, making it close.
Well, but still there is a question: How to make invokation of workflow synchronously?
Thanks,
Konstantin.
Saturday, June 2, 2007 5:07 PM -
KV,
- for more robust solution, the private queue can be avoided using the IEventActivity, IActivityEventListener<QueueEventArgs> implementation in the CallWorkflowActivity class and writing a callback message into the persisted queue using the Unload method.
- this event driven activity will allow to use a "WatchdogTimer" for lifetime of the child workflow processing in the listenActivity scope.
Thanks
Roman
Saturday, June 2, 2007 7:49 PM -
Yep - that would be a bug. I'll have to figure out how to make it work in light of persistence - shoudl have that of that up front - but part of the sample is about the designer as well (not just the sync call workflow).
Likely I'll put a DependencyProperty inside of the called workflow and then also have the service subscribe to the WorkflowLoaded event.
Sunday, June 3, 2007 3:48 AM -
Hi,
I hope that I solved the problem of calling workflow from another workflow synchronously, being in the same "context" (strictly speaking it is different execution context for sure) as caller. Btw, there was similar thread: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=511416&SiteID=1.
I did like this: I have created the activity, which at design time adds callee workflow to the activity. Then at runtime, I execute this workflow as if it is an activity, subscribing to it's Closed event and passing parameters back to caller on that event. In such a way we do not have dependancy on persistence service. The mechanism of parameters discovery is the same as Jon Flanders sample. And such created activity does not need to have service.
Launching workflow using standard activity and waiting for it's completion through event in case of presence of persistence service requires creation of persistence point before launching of callee. If we do not do this, then in case of crash, we will launch second instance of callee or we need to implement some mechanism of preventing it.
For sure, it is possible to create composite activity to have it as a callee, but this creates more problems, then above mentioned method. (For example validation of parameters at design time). Using above mentioned approach., developer can operate in terms of workflows, not knowing how to create activities. (Like in BizTalk - developer creates orchestration and just calls it from another orchestration or runs it separately).
Any comments on such approach will be highly appreciated. Maybe I missed something?
Thanks,
Konstantin.
Friday, June 15, 2007 2:21 PM -
All you are doing then is executing another activity - you aren' starting a new Workflow.Friday, June 15, 2007 2:51 PM
-
Exactly. And this new 'activity' is a workflow actually.
Friday, June 15, 2007 4:44 PM -
No - to have a "workflow" you have to go through the WorkflowRuntime.CreateWorkflow method. What you have is a child activity. Even if that activity is SequentialWorkflowActivity - remember there is no special "Workflow" type.Friday, June 15, 2007 6:33 PM
-
Sure. It is a child activity. Do you see any problems with this approach?
Friday, June 15, 2007 8:21 PM -
I guess I never replied on this thread - but just for documentation purposes - if you download the sample code now - http://www.masteringbiztalk.com/blogs/jon/PermaLink,guid,7be9fb53-0ddf-4633-b358-01c3e9999088.aspx it will deal with persistence correctly.Sunday, August 12, 2007 10:07 PM
-
Hi, Konstantin!
Your solution seems very good to me and it suits exactly to what I need.
Could you please post the source code online ?
Best Regards,Thursday, November 19, 2009 10:56 AM