问题
Been trying to execute tasks sequentially but they are executed in a random order instead.
- Appending .Unwrap after .ContinueWith doesn't help
- Returning a Task of T from these methods instead of Task and assigning their result in the caller doesn't work either
Not sure about signature of my methods, whether they should contain async/await or not.
Sequencing tasks :
Task biographies = LoadArtistBiographies(apiKey);
Task blogs = LoadArtistBlogs(apiKey);
Task familiarity = LoadArtistFamiliarity(apiKey);
Task hottness = LoadArtistHottness(apiKey);
Task images = LoadArtistImages(apiKey);
await biographies.ContinueWith(b => blogs);
await blogs.ContinueWith(f => familiarity);
await familiarity.ContinueWith(h => hottness);
await hottness.ContinueWith(i => images);
await images;
Sample of executed methods :
private async Task LoadArtistBiographies(string apiKey)
{
var parameters = new ArtistBiographiesParameters();
parameters.SetDefaultValues();
parameters.ApiKey = apiKey;
parameters.Id = _artistId;
ArtistBiographies biographies = await Queries.ArtistBiographies(parameters);
ItemsControlBiographies.ItemsSource = biographies.Biographies;
}
The Queries.* methods are also asynchronous :
public static async Task<ArtistBlogs> ArtistBlogs(ArtistBlogsParameters parameters)
What is the correct syntax for chaining tasks that themselves are executing asynchronous tasks ?
回答1:
If you want to execute the tasks in a specific order, you should await
them directly:
await LoadArtistBiographies(apiKey);
await LoadArtistBlogs(apiKey);
await LoadArtistFamiliarity(apiKey);
await LoadArtistHottness(apiKey);
await LoadArtistImages(apiKey);
This will cause the second task (LoadArtistBlogs
) to be scheduled after the first task completes.
Right now, the tasks are executing "in random order" because you've assigned them to Task
instances, which allows each to be executed simultaneously.
That being said, I would actually recommend changing your methods around to returning the values, instead of assigning them to the datasource within the method:
private async Task<Biographies> LoadArtistBiographiesAsync(string apiKey)
{
var parameters = new ArtistBiographiesParameters();
parameters.SetDefaultValues();
parameters.ApiKey = apiKey;
parameters.Id = _artistId;
var bio = await Queries.ArtistBiographies(parameters);
return bio.Biographies;
}
You could then write these as:
ItemsControlBiographies.ItemsSource = await LoadArtistBiographiesAsync(apiKey);
// Other methods below, with await as this example
This makes the intent as the logic flows through the async methods a bit more clear, in my opinion.
回答2:
Your example code will start executing all the tasks without waiting for each one to complete. It then waits for them to complete in order.
The key is that an async
method starts when you call it. So if you don't want to start it yet, don't call the method yet:
await LoadArtistBiographies(apiKey);
await LoadArtistBlogs(apiKey);
await LoadArtistFamiliarity(apiKey);
await LoadArtistHottness(apiKey);
await LoadArtistImages(apiKey);
回答3:
await
will wait for the given task to complete, it will not start the task. Your Load*-methods all most likely start a task. All five tasks are running in an arbitrary order.
At the point when you get to await
, your task may already has finished or not. It does not matter. You call ContinueWith
on it, telling your task it should continue with this method once finished. This will return a new Task, on which you finally await.
回答4:
Actually I've just found a way but without ContinueWith :
ArtistBiographies biographies = await LoadArtistBiographies(apiKey);
ItemsControlBiographies.ItemsSource = biographies.Biographies;
ArtistBlogs blogs = await LoadArtistBlogs(apiKey);
ItemsControlBlogs.ItemsSource = blogs.Blogs;
ArtistFamiliarity familiarity = await LoadArtistFamiliarity(apiKey);
ContentControlFamiliarity.Content = familiarity.artist;
ArtistHotttnesss hottness = await LoadArtistHottness(apiKey);
ContentControlHottness.Content = hottness.Artist;
ArtistImages images = await LoadArtistImages(apiKey);
ItemsControlImages.ItemsSource = images.Images;
Curious if someone could provide the answer using ContinueWith.
来源:https://stackoverflow.com/questions/17153162/continuation-tasks-not-executing-in-correct-order