Search code examples
workflow-foundation-4workflow-foundation

Windows Workflow fails when sending a message to a completed workflow


I have a workflow that manages contacting people over the phone. It is designed to call a series of numbers until answered or an expiration time is reached. I receive the error below when the workflow is completed following the expiration period, but is in the middle of a phone call. As a result a hangup message is sent to the completed workflow and fails.

How can I detect the workflow has been completed when receiving the hangup message?

System.ServiceModel.FaultException: The execution of an InstancePersistenceCommand was interrupted because the instance 'a9ecca9f-9edd-4dd0-939c-2a7091a6b59c' is already complete.

Server stack trace:
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

enter image description here


Solution

  • This is a pretty fundamental problem with Workflow Services - there are no guarantees that your workflow is in a proper state to receive the incoming message, and if it's not you get an obscure error. There are too many conditions where the workflow won't be ready, such as a workflow faulted on some transient error that can be retried. To make your code robust you pretty much always need to validate the incoming call to check that the workflow is waiting on that event, and possibly record the event so it can be acted on when the workflow gets into that state. I've found it best to manage the bookmarks myself rather than relying on the WCF send and receive activities, and have the service operations to wake a workflow just be normal WCF operations that record the event, with a separate polling process to attempt to wake the workflow, with retry if the workflow isn't in the right state yet.