并行处理三个数据库操作

时间:2018-07-14 18:22:49

标签: c# async-await entity-framework-core

我仍在加快异步/等待的速度,我主要是作为学习中的问题来问这个问题。

我有这种方法,可以简单地连续创建三个对象。

问题是,这些实际上是否在并行处理?意味着多线程?

还是每个人在开始之前实际上都在等待最后一个完成?

autoFocus

是否有一种更有效的方式来按照async / await来编写代码,例如await all? (除了创建所有三个并保存一次的明显方法之外)。据我了解,EntityFrameworkCore不支持并行性,在这种情况下,我为每个HttpRequest使用单个上下文。

1 个答案:

答案 0 :(得分:2)

让我们从基础开始,然后转到EF专用代码。

  

问题是,这些实际上是否在并行处理?意味着多线程?

  1. 否,并行和异步处理是不同的。没有什么可以使前面的代码并行运行,实际上,它们都是顺序的。

  2. 否,asyncawait关键字无法创建,也不能与Thread一起使用。

请注意,您可以从async中删除awaitAddChildAsync关键字,这是不必要的。

如果想要以并行,异步的方式运行代码,则可以这样做:

await Task.WhenAll(
    this.AddChildAsync(project, "Task A", Enums.ItemTypes.Task),
    this.AddChildAsync(project, "Task B", Enums.ItemTypes.Task)
    this.AddChildAsync(project, "Task C", Enums.ItemTypes.Task)
);

这将同时启动和运行所有三个任务。

然而DbContext操作不是线程安全的,并且以上代码极有可能发生严重故障。

有两种处理方法:

  1. 使AddChildAsync产生自己的DbContext实例。这将允许您使用我之前提到的并行代码。
  2. 再创建一个AddChildAsync,它不保存更改,或者使布尔值用于确定是否保存。这样,您仅在将所有三个实体都添加到上下文之后才调用数据库。虽然是顺序的,但是比上面代码中的并行处理要容易。