foreach 循环中任务/等待的最佳实践

Ste*_*vds 3 c# asp.net-mvc optimization async-await

我在使用任务/等待的 foreach 中有一些耗时的代码。它包括从数据库中提取数据、生成 html、将其发布到 API 以及将回复保存到数据库。

模型看起来像这样

List<label> labels = db.labels.ToList();
foreach (var x in list) 
{
    var myLabels = labels.Where(q => !db.filter.Where(y => x.userid ==y.userid))
                         .Select(y => y.ID)
                         .Contains(q.id))

    //Render the HTML
    //do some fast stuff with objects

    List<response> res = await api.sendMessage(object);  //POST

    //put all the responses in the db
    foreach (var r in res) 
    {
        db.responses.add(r);
    }

    db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

从时间上看,生成 Html 并将其发布到 API 似乎花费了大部分时间。

理想情况下,如果我可以生成下一个项目的 HTML,并等待帖子完成,然后再发布下一个项目,那就太好了。

也欢迎其他想法。人们会怎样做呢?

我首先想到Task在上面添加一个foreach并等待其完成然后再进行下一个 POST,但是我如何处理最后一个循环......感觉很混乱......

Aka*_*ava 5

您可以并行执行,但每个任务都需要不同的上下文。

实体框架不是线程安全的,因此如果您不能在并行任务中使用一个上下文。

var tasks = myLabels.Select( async label=>{
    using(var db = new MyDbContext ()){
        // do processing...
        var response = await api.getresponse();
        db.Responses.Add(response);
        await db.SaveChangesAsync();
    } 
});

await Task.WhenAll(tasks);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,所有任务似乎都是并行运行的,并且每个任务都有自己的上下文。

如果您不为每个任务创建新的上下文,您将收到此问题实体框架支持并行异步查询吗?