函数不等待foreachAsync结束

时间:2019-07-25 15:02:41

标签: c# .net linq asynchronous core

我尝试用从异步操作到数据库的数据填充模型。 问题是尽管我正在等待调用,该函数仍会返回View(没有完整的模型)。

我尝试放置一个计时器(我知道这不是解决方案),以确保问题来自异步,我还尝试在我的foreachAsync内部添加一些代码注释,这似乎没有帮助

我得到一个项目列表,其中填充了一些附加信息,最后,我将对象分配给我的模型,然后返回视图

public async Task<IActionResult> newProjetList(int GestionaireId, int VilleId)
        {
            ProjetListModel model = new ProjetListModel();
            ProjetService projetService = new ProjetService(connectionString);
            UserServices userServices = new UserServices(connectionString);
            AvancementService avancementService = new AvancementService(connectionString);
            VilleService villeService = new VilleService(connectionString);
            List<Projet> projets = await projetService.NewProjetLine(GestionaireId, VilleId);

            await projets.ToAsyncEnumerable().ForEachAsync(async p =>
            {
                int villeId = await villeService.getVilleIdByProjetId(p.ProjetId);
                Ville ville = await villeService.GetById(villeId);
                p.Ville = ville.VilleLabel;
                p.GestionnaireProjet = await userServices.GetNameById(p.GestionnaireProjetId ?? 0);
                await p.SousProjet.ToAsyncEnumerable().ForEachAsync(async sp =>
                 {
                     sp.Avancement = await avancementService.GetLabelById(sp.AvancementId);
                 });
            });
            model.projets = projets;
            //System.Threading.Thread.Sleep(5000);
            return View("ProjetList", model);
        }

我希望输出中缺少信息(这里是“ ville”,“ gestionnairesProjet”和“ Avancement”

谢谢您的回答,对不起,我的代码中的一些法语词汇:p

1 个答案:

答案 0 :(得分:2)

ForEachAsync只需要一个Action<...>,而不是一个Func<..., Task>,因此您的代码传递给async的{​​{1}} lambda变成了{{3} }。应当避免使用ForEachAsync的主要原因之一是,确定方法何时完成并不容易-实际上,在这种情况下,没有任何东西可以确保在发送响应之前完成该方法。

我建议按照Marc的建议进行操作,并且仅使用async void

foreach

或者,如果您要使用异步并发,则可以使用List<Projet> projets = await projetService.NewProjetLine(GestionaireId, VilleId); foreach (var p in projects) { int villeId = await villeService.getVilleIdByProjetId(p.ProjetId); Ville ville = await villeService.GetById(villeId); p.Ville = ville.VilleLabel; p.GestionnaireProjet = await userServices.GetNameById(p.GestionnaireProjetId ?? 0); foreach (var sp in p.SousProject) { sp.Avancement = await avancementService.GetLabelById(sp.AvancementId); } } model.projets = projets;

Task.WhenAll