My task is to write a known nr of values to an external system by using an (async) interface. I have to limit the maximum number of parallel writes that are executed concurrently. Additionally I've got to use load balancing because it may take longer for some values to be written by that external system.
I know how to solve these problems each on it's own:
Degree of parallelism:
new ParallelOptions {MaxDegreeOfParallelism = maxNrParallelWrites}
I also stumbled over this article: http://msdn.microsoft.com/en-us/library/ee789351(v=vs.110).aspx
Load balancing:
var partitioner = Partitioner.Create(values.ToList(), true);
Task from async interface:
var writeTask = Task<AccessResult>.Factory.FromAsync(BeginWriteValue, EndWriteValue, value.SystemId, value.Xml, priority, null);
But how do I correctly combine all this techniques? I created the following code:
int maxNrParallelWrites = GetMaxNrParallelWrites();
var partitioner = Partitioner.Create(values.ToList(), true);
Parallel.ForEach(partitioner, new ParallelOptions {MaxDegreeOfParallelism = maxNrParallelWrites},
(val) =>
{
var writeValueTask = GetWriteValueTask(val, priority);
Task.WaitAny(writeValueTask);
});
I'm especially unsure about the the last part of the previous code: the action that executes the workload. Would it be better instead of creating a WriteValueTask directly use the synchronous interface like this:
(val) =>
{
var accessResult = externalSystem.WriteValue(....);
}
Or is it okay to create a task and then directly wait for it (Task.WaitAny(...))?