Which code pattern is best for handling a cyclical and changeable flow of actions

290 views Asked by At

My scenario is an application working cyclically on real time data and with tigh deadlines.

I have a serie of actions to take on data at each cycle. I've actions that take place at each cycle (let's call them with capital letters like A, B, C..) and other actions that take place only every x cycles (let's call them with lowercase letters like d, e, f,...). A flow pattern example, having two persistent actions and one taking place with a period of 3 cycle could be (end of cycle is marked by '|'):

A - B - d | A - B | A - B | A - B - d |...

Moreover, the pattern could change at runtime accordingly to users' input. So some actions could be added or removed from the list. For instance, the previous pattern by removing B, adding C after A and e after C with a period of 2 cycles would suddenly become (change cycle marked by '->'):

...| A - B - d | -> A - d - C - e | A - C | A - C - e | A - d - C | A - C - e | A - C | A - d - C - e |...

Right now I start manually threads that communicate each other through WaitHandles and that, in case the action is heavy, make use of Parallel.For. Then when the pattern changes I may have for instance to terminate a certain thread, launch another one, substitute the WaitHandle on which to wait on... I have deadlock problems that arise when the pattern changes. I could fix them, but I came to the idea that it would be much better to have a more flexible solution, so that if I need to change the pattern later on, I've already all the tools to do it efficiently.

I'm pretty new on this topic but I think (following also what it has been suggested to me previoulsy) I need a sort of scheduler.

I've read something about Windows Workflow Foundation (I do not know at the moment whether it's suitable for my situation) and other solutions but I would need to know the best direction to take before spending time on understanding it. For instance Tasks are more suitable for this? Or should I stick on threads and create a Scheduler class for managing all possible situations (In this case I see already different issues on the changing of patterns and I would be greatful if you could go deeper into the problem)? Or there are better alternatives?

[EDIT]
Actions can be executed when the previous main action (A, B,...) in the cycle has terminated. Minor actions (d, e,...) can be executed concurrently. For instance in a cylcle of type A - B - d - e action B can be executed only after A, action d only after B and action e only after B and also possibly concurrently with d. Moreover, if I do not group two successive main actions (in the example one might think that A and B could be grouped into one single action because of their interdependency) it means that are executed in two different threads. The reason for this is that I use circular buffers for storing intermediate results (in the example the result coming from A and that will be later used by B). Buffers help me on not losing data during the real time process in case for some reason there is a delay in the process (in fact the main leader action A will always occur with a good timing accuracy regardless the last action in the cycle has finished or not).

1

There are 1 answers

5
VulgarBinary On

I would recommend looking into windows workflow and binding delegates to a state machine state changes.

You could track the cycle count CycleIteration = cycle++ % MaxCycleCount

And trigger the cycle loop based on which iteration.

You would have a work flow for each cycle iteration so call it:

Cycle Iteration 0: A - B - d

Cycle Iteration 1: A - B

Cycle Iteration 2: A - B

Cycle Iteration 3: A - B - d

...

Each cycle state change in the Workflow state machine is based on iteration count. Your each individual method would have a delegate defined as a work item wrapped in a delegate for re-use.

Each Cycle Iteration workflow would be saved and called by the FSM, and would look like:

CycleIteration1Execute(...){ callA(...); callB(...); callD(...); return; }

Then modification of cycle order and cycle states would be maintained in small logical easily maintained chunks.

Edit (Providing examples for WF implementation):

Example of WF Finite State Machine: This is a VERY beginner example that illustrates how to do a 2 state FSM.

http://www.codeproject.com/KB/dotnet/FirstStateMachineWorkflow.aspx

Example provided by M$ (As with all their examples, very wordy but gives a bit more involved example):

http://msdn.microsoft.com/en-us/magazine/cc163281.aspx

And the best for last, a very well put together blog post on a State Machine using WF

http://odetocode.com/code/460.aspx