async 如何防止并行执行导致的错误?
How does async prevent errors caused due to parallel execution?
使用 await 如何使代码线程安全?
Entity Framework Core does not support multiple parallel operations
being run on the same DbContext instance. This includes both parallel
execution of async queries and any explicit concurrent use from
multiple threads. Therefore, always await async calls immediately, or
use separate DbContext instances for operations that execute in
parallel.
假设 1 db 调用正在进行中,线程 1 正在运行。当它在其中工作时;
案例一:
假设我没有使用异步。并行调用由另一个线程进行,因此会发生冲突和错误。
案例二:
假设我使用异步。另一个线程进行并行调用:
案例2.a:由于我们使用async,当第一个线程发出请求,等待响应时,它会释放线程,这样线程2在发出请求时不会发生冲突。我明白这一点。
案例2.b如果两个线程真的同时发出请求怎么办
情况 2.b 可行吗?使用异步是否有帮助?
你遗漏的是,在 ASP.NET Core 的常见情况下,DbContext 的范围仅限于 HTTP 请求,框架保证只有一个中间件或控制器方法 运行 随时请求。因此 await
异步调用足以防止并行 DbContext 访问。
“始终立即等待异步调用”意味着避免启动多个异步操作并等待它们稍后完成(就像处理多个 HTTP 请求一样)。
下面是一个典型的示例,说明应该对异步 HTTP 调用执行哪些操作但对 EF 操作无效:
// start operations early so results are there after our CPU intensive code complete
var task1 = dbContext.GetSomething();
var task2 = dbContext.GetMore();
// do something slow here to let both operations to finish
var result1 = await task1;
// even more code
var result2 = await task2;
此代码将使对 运行 的两个操作并行进行,从而可能导致 dbContext 出现问题。
指导建议:
var result1 = await dbContext.GetSomething();
var result2 = await dbContext.GetMore();
// run slow code now sequntially to avoid parallel calls to dbContext.
事实上,如果你小心的话,你可以对 DBContext 的调用和对不相关对象的其他操作进行类似的交错 - 即并行的 HTTP 调用和 DBContext 调用,或者 DBContext 调用和 CPU 密集代码 运行 与 EF 调用的晚期 awiat
并行。
请注意,该指南对于在两个线程之间共享上下文没有多大帮助 - 与任何非线程安全对象一样,您有责任防止同时访问此类共享对象。
使用 await 如何使代码线程安全?
Entity Framework Core does not support multiple parallel operations being run on the same DbContext instance. This includes both parallel execution of async queries and any explicit concurrent use from multiple threads. Therefore, always await async calls immediately, or use separate DbContext instances for operations that execute in parallel.
假设 1 db 调用正在进行中,线程 1 正在运行。当它在其中工作时;
案例一:
假设我没有使用异步。并行调用由另一个线程进行,因此会发生冲突和错误。
案例二:
假设我使用异步。另一个线程进行并行调用:
案例2.a:由于我们使用async,当第一个线程发出请求,等待响应时,它会释放线程,这样线程2在发出请求时不会发生冲突。我明白这一点。
案例2.b如果两个线程真的同时发出请求怎么办
情况 2.b 可行吗?使用异步是否有帮助?
你遗漏的是,在 ASP.NET Core 的常见情况下,DbContext 的范围仅限于 HTTP 请求,框架保证只有一个中间件或控制器方法 运行 随时请求。因此 await
异步调用足以防止并行 DbContext 访问。
“始终立即等待异步调用”意味着避免启动多个异步操作并等待它们稍后完成(就像处理多个 HTTP 请求一样)。
下面是一个典型的示例,说明应该对异步 HTTP 调用执行哪些操作但对 EF 操作无效:
// start operations early so results are there after our CPU intensive code complete
var task1 = dbContext.GetSomething();
var task2 = dbContext.GetMore();
// do something slow here to let both operations to finish
var result1 = await task1;
// even more code
var result2 = await task2;
此代码将使对 运行 的两个操作并行进行,从而可能导致 dbContext 出现问题。
指导建议:
var result1 = await dbContext.GetSomething();
var result2 = await dbContext.GetMore();
// run slow code now sequntially to avoid parallel calls to dbContext.
事实上,如果你小心的话,你可以对 DBContext 的调用和对不相关对象的其他操作进行类似的交错 - 即并行的 HTTP 调用和 DBContext 调用,或者 DBContext 调用和 CPU 密集代码 运行 与 EF 调用的晚期 awiat
并行。
请注意,该指南对于在两个线程之间共享上下文没有多大帮助 - 与任何非线程安全对象一样,您有责任防止同时访问此类共享对象。