This is not behaving quite as I thought it would the need is simple, launch a number of tasks to do operations on an object. One unique object per task. The second part is a ContinueWith
when each task reports the results. However, I am not getting a WhenAll
type behavior. Hopefully someone can set me straight.
_tasks = new Task<AnalysisResultArgs>[_beansList.Count];
for (int loopCnt = 0; loopCnt < _beansList.Count; loopCnt++)
{
_tasks[loopCnt] = Task<AnalysisResultArgs>.Factory.StartNew(() =>
{
return _beansList[loopCnt].Analyze(newBeanData);
});
await _tasks[loopCnt].ContinueWith(ReportResults,
TaskContinuationOptions.RunContinuationsAsynchronously)
// do some housekeeping when all tasks are complete
}
private void ReportResults(Task<AnalysisResultArgs> task)
{
/* Do some serial operations
}
It was my understanding that _beansList.Count
tasks would be launched and by using await
on the ContinueWith
the housekeeping work won't execute until all the Tasks have completed. I cannot block, as I need to be sure to be able to throttle the incoming data to prevent way too many tasks waiting to be executed.
Where did I goof, the await actually completes and the housekeeping gets run even though not ALL of the tasks have run to completion.
You do not await all the tasks, you're awaiting the continuation in loops. You should use the
Task.WhenAll
method for this. Also, why do you need the continuation, if you can run it inside task? Simplify your code like this:As @Stephen has already mentioned, the code in the question is not minimum, complete and verifiable. I have taken some liberty to make some assumptions and that's how in my view your code shall look like:
Assumptions / Other details:
Task.Delay
andTask.FromResult
are the mere place holders of actual logic.Analyze
andReportResults
are AsyncIn the loop code could have been:
but if we are using
Task.Run
to start aTask
, thenasync, await
helps in freeing up the calling thread pool thread / synchronization context. It helps in improving the system scalability._beansList
is of typeList<AnalysisResultArgs>
, but that can be modified based on actual requirementReportResults
could be modified to take aFunc<Task<AnalysisResultArgs>> func
, instead of simple dTask<AnalysisResultArgs>
, thus doingawait func()
inside the method and then the calling code could have been truly async as follows: