继续任务未按正确顺序执行

时间:2013-06-17 17:16:12

标签: c# async-await

尝试按顺序执行任务,但它们是以随机顺序执行的。

  • 在.ContinueWith之后附加.Unwrap
  • 从这些方法而不是任务中返回T的任务并在调用者中分配他们的结果也不起作用

不确定我的方法的签名,是否应该包含async / await。

排序任务:

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;

已执行方法的示例:

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;
}

Queries。*方法也是异步的:

public static async Task<ArtistBlogs> ArtistBlogs(ArtistBlogsParameters parameters)

链接自己执行异步任务的任务的正确语法是什么?

4 个答案:

答案 0 :(得分:6)

如果您想按特定顺序执行任务,则应直接await

await LoadArtistBiographies(apiKey);
await LoadArtistBlogs(apiKey);
await LoadArtistFamiliarity(apiKey);
await LoadArtistHottness(apiKey);
await LoadArtistImages(apiKey);

这将导致在第一个任务完成后安排第二个任务(LoadArtistBlogs)。

现在,任务正在“按随机顺序”执行,因为您已将它们分配给Task个实例,这样可以同时执行每个实例。

话虽如此,我实际上建议您更改方法以返回值,而不是将它们分配给方法中的数据源:

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;
}

然后你可以将它们写成:

ItemsControlBiographies.ItemsSource = await LoadArtistBiographiesAsync(apiKey);
// Other methods below, with await as this example

在我看来,这使得逻辑在异步方法中流动的意图更加清晰。

答案 1 :(得分:2)

您的示例代码将启动执行所有任务,而无需等待每个任务完成。然后它会按顺序等待完成

关键是当你调用它时会启动async方法。因此,如果您还不想启动它,请不要调用该方法:

await LoadArtistBiographies(apiKey);
await LoadArtistBlogs(apiKey);
await LoadArtistFamiliarity(apiKey);
await LoadArtistHottness(apiKey);
await LoadArtistImages(apiKey);

答案 2 :(得分:1)

await将等待给定任务完成,它将无法启动任务。你的Load *方法最有可能开始一项任务。所有五个任务都以任意顺序运行。

当你到达await时,你的任务可能已经完成了。不要紧。你打电话给ContinueWith,告诉你的任务一旦完成就应该继续使用这个方法。这将返回一个新的Task,最后等待你。

答案 3 :(得分:0)

实际上我刚刚找到了一种方法但没有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;

如果有人可以使用ContinueWith提供答案,那就很好奇。