I've been toying with parallelism and I'm having some trouble understanding what's going on in my program.
I'm trying to replicate some of the functionality of the XNA framework. I'm using a component-style setup and one way I thought of making my program a little more efficient was to call the Update method of each component in a separate Task. However, I'm obviously doing something horribly wrong.
The code I'm using in my loop for an update call is:
public void Update(GameTime gameTime)
{
Task[] tasks = new Task[engineComponents.Count];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = new Task(() => engineComponents[i].Update(gameTime));
tasks[i].Start();
}
Task.WaitAll(tasks);
}
This throws a weird error:
An unhandled exception of type 'System.AggregateException' occurred in mscorlib.dll
The inner exception talks about an index being out of range.
If I change
Task[] tasks = new Task[engineComponents.Count];
to
Task[] tasks = new Task[engineComponents.Count - 1];
then this seems to work (or at least the program executes without an exception), but there isn't enough room in the array for all of the components. Nonetheless, all of the components are updated, despite there not being enough room in the tasks array to hold them all.
However, the gameTime object that is passed as a parameter goes somewhat insane when the game is running. I've found it hard to pin-point the problem, but I have two components that both simply move a circle's x-position using
x += (float)(gameTime.ElapsedGameTime.TotalSeconds * 10);
However, when using Tasks, their x-positions very quickly become disparate from one another, when they should in fact be the same. Each engineComponent.Update(gameTime) is called once per-update cycle, and the same gameTime object is passed.
When using tasks[i].RunSynchronously(); in place of tasks[i].Start();, the program runs exactly as expected.
I understand that using Tasks in this manner may not be a particularly efficient programming practice, so my question is one of curiosity: why isn't the above code working as I would expect? I know I'm missing something obvious, but I've been unable to track down what specifically is wrong with this implementation.
Apologies for the long question, and thanks for reading ;)