asp.netwcfiisworkflow-foundation-4workflowservice

WF4 WCF Send Message at wrong time


I am hosting a workflow service (xamlx) in IIS. It has some Receive Activities, e.g. MethodA and MethodB. I wrote a MVC pplication as client to call these methods. In PageA, user submits the form will call MethodA, the workflow would goes to the Receive Activity that waiting for MethodB. Then in Page B, user submits the form will call MethodB. However, if user submits in PageA and then go back to PageA and submit again for the same workflow instance, it will wait a minute and give a timeout exception:

The request channel timed out while waiting for a reply after 00:01:00. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.

This error seems come from WCF while I suppose it will give the following error:

The execution of an InstancePersistenceCommand was interrupted because the instance key 'guid' was not associated to an instance. This can occur because the instance or key has been cleaned up, or because the key is invalid. The key may be invalid if the message it was generated from was sent at the wrong time or contained incorrect correlation data.

I have a few questions:

  1. Is there any configuration we can set so that another exception can be caught instead of waiting for some time until a timeout exception can be caught? I know we can set a smaller timeout value in binding tag but it shouldn't be a solution.

  2. Is there any way to avoid PageA to be shown when workflow instance is not in a correct state? (Even this is done, we also need to solve problem 1 as the user could open PageA and idle for some time before submit)

Thanks.


Solution

  • Re: the timeout exception.

    This is a known bug in WF4. It is the result from the fact that the WF/WCF infrastructure will try to deliver a message. That means that it will hang on to the message for a bit and see if the workflow gets to a state where it can process the message. The infrastructure doesn't really know about the structure of your workflow. So even while you are fully aware that the workflow is in a state that it will never be a able to process the message given the current state the infrastructure will wait.

    Re: Avoiding PageA being shown.

    This is really up to the UI layer and outside of the scope of the workflow. And as you pointed out not completely avoidable. However I have had good success with using the bookmark information in the persistence store. Each Receive activity creates a bookmark with a known name and I basically checked for the bookmarks in there. Based on this information I would enable/disable parts of the UI. It will not really solve the problem of a user opening a page and leaving it like that for 15 minutes so you still need an error handler when you call the service method. One way of improving on that is, assuming an HTML bases UI for a moment, to use WebSockets, or SignalR to be more practical, and push workflow state changes from the server to the client. Still won't eliminate the need for error handling but should make the window with UI in the wrong state much smaller.