I'm new to multi-tasking, however I'm trying to learn how it all works. I have the following code, which I thought would create a task and run the performInitialLoad method, and when that completes, would then fire off the initializeDataHarvester method. The performInitialLoad works fine, and it does reach the bottom of the method because I can see the text "Initial tag data load complete" in my console. But it never seems to fire the initializeDataHarvester method. Any ideas?
private void mainTaskLoader() {
Task initialLoad = new Task(performInitialTagLoad);
initialLoad.Start();
Task dataHarvester = new Task(() => {
Task.WhenAll(initialLoad);
}).ContinueWith(t => initializeDataHarvester());
}
private void performInitialTagLoad() {
allTags = globals.getTags();
foreach (KeyValuePair<String, String> tag in allTags) {
try {
globals.insertUpdateHarvesterData(tag.Key.ToString(), commObject.Read(tag.Value.ToString()));
} catch (Exception e) {
Console.WriteLine("Error on initial load: " + e.Message, true);
}
}
Console.WriteLine("Initial tag data load complete");
}
private void initializeDataHarvester() {
Console.WriteLine("Got here!");
}
Task.WhenAll
returns immediately - but it returns a task which will complete when the tasks have completed. You're ignoring that return value at the moment. You're also not starting the task which calls WhenAll
, which is why that task is never completing.
You could just use:
Task.WhenAll(initialLoad).ContinueWith(...);
... but better yet, you could just avoid using WhenAll
at all, given that you've only got a single task anyway.
You should also:
With async/await, this code would be something like:
private async Task MainTaskLoader()
{
await Task.Run(PerformInitialTagLoad);
InitializeDataHarvester();
}
If you genuinely have multiple things to run, you could use:
private async Task MainTaskLoader()
{
var task1 = Task.Run(PerformInitialTagLoad);
var task2 = Task.Run(SomethingElse);
// Imagine we have many of these...
await Task.WhenAll(task1, task2);
InitializeDataHarvester();
}
Ideally, you'd make PerformInitialTagLoad
an async method as well, mind you - which would require making the insertion async too.
See more on this question at Stackoverflow