WF: Delay activity in workflow as a concept

Recently, I have come across a case, where a lot of questions are being raised around delay activity (https://msdn.microsoft.com/en-us/library/system.activities.statements.delay(v=vs.110).aspx) in a workflow service application. To summarize, I am sharing the essence out of it.

WF service

Designed WF service (.xamlx) with a delay delay1

 

Please note the Delay activity is introduced between ReceiveRequest and SendResponse.  It means application will be delayed by the Delayed duration.

 

Service behavior configuration looks like:

 <behaviors>
     <serviceBehaviors>
         <behavior>
             <sqlWorkflowInstanceStore connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Persistence;Integrated Security=True;Asynchronous Processing=True;"/>
             <workflowIdle timeToUnload="00:00:00"/>
         </behavior>
      </serviceBehaviors>
</behaviors>

Client application

It consumes the WF service same as an ordinary WCF service is consumed.

     class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i < 20; i++) { Task.Run(() => MyMethod(i));
            }
            Console.ReadLine();
        }
 
        private static void MyMethod(int i)
        {
            var proxy = new ServiceClient("BasicHttpBinding_IService");
            var results = proxy.GetData(new GetDataRequest { @int = 123*i+i });
            Console.WriteLine(DateTime.Now.ToString()+ " .. "+ results.@string);
        }
    }

After the console application is called, let’s switch to SQL server Persistence database and look in [InstancesTable] sql table.

delay2

 

 

 

 

PendingTimer is null because activity has not been completed on the service side yet. Instance is unloaded just because of the delay. However, IsInitialized is still set to 0 as activity is incomplete.

If you get a scenario where you have PendingTimer value appearing NULL, it means there is certain unexpected application scenario that it went through and unloaded the instance abruptly. To diagnose this kind of challenge, workflow ETW tracing should be taken and reviewed (and check if we have any application level failures).

 

Now, if we move the Delay activity next to SendResponse for service application like:

delay3

 

Let’s make the client call as being done above for the service. Then, switch our focus to SQL server Persistence database SQL table [InstancesTable]. The table would appear like the following:

delay4

This time WF instance is persisted after the activity completed. That is why we have values in PendingTimer, ExecutionStatus as Idle, and IsInitialized as 1.

 

Once the system time reaches the pending timer value, instance gets removed from SQL and loaded back in memory.

 

I hope this helps!