May 16, 2010

Beware of Simio's parallelism

I recently ran into a problem that was really hard to track down because Simio until sprint 37 did not return the complete stack trace when an exception was thrown. Anyway, the Simio support team was so kind to send me the whole information, which ultimately led me to the solution.

The weird thing was that the error only occured when I tried to run the model in an experiment with multiple replications. The model executed fine from the modeling UI, and also with an experiment with a single replication. What could that be?

The error message then was:

Collection was modified; enumeration operation may not execute

Knowing that I used a generic list in my custom step from where the exeception was thrown, this could be the only source of the problem. A short internet search revealed that obviously generics in C# are not "thread-safe", in other words if they run in a parallel environment you have to take care of who can access the collection and when; otherwise the above exception is thrown when you try to enumerate through its members. But why is my step subject to changes from different threads in the first place? Shouldn't Simio create a new step instance for each scenario or replication? The answer is no!

After sending my code to the Simio support team, I got the hint that Simio only instantiates a step once (for all experiment scenarios and replications) and uses the simulation context object (IExecutionContext) to relate to the current context of the scenario or replication. On the other side, elements are instantiated for each single replication. The implications are to remove all members like my List from the step class and move it to an element. This should avoid the weird side-affects!

That's it! Now it works even if I run the model with an experiment and multiple replications.