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

标签 c# asp.net-mvc optimization async-await

我在使用 task/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();
}

就时间而言,生成 Html 并将其发布到 API 似乎花费了大部分时间。

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

也欢迎提出其他想法。 如何解决这个问题?

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

最佳答案

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

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

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

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

如果您不为每个任务创建新的上下文,您将在这个问题 Does Entity Framework support parallel async queries? 中得到错误提示

关于c# - foreach 循环中任务/等待的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31714635/

相关文章:

excel - VBA宏快速删除行

c - 高效计算 2 的幂

c# - 通过 ASP.NET C# 发送 HTTP 请求

c# - 无法传递字符串数组

c# - 在单独的后台线程与进程中运行长时间后台任务

jquery - ASP.Net MVC JQuery 在 IE8 中未定义,但在 Chrome 中可以

c# - 如何从 API 获取数据并将其插入数据库而不在 ASP.NET MVC 中重复?

asp.net - 使用 RouteMagic MVC 保留查询字符串参数

haskell - 运行一次子表达式

c# - Process.Start() 是否以任何方式连接到可执行文件中?