【发布时间】:2018-04-14 21:50:54
【问题描述】:
我搜索了很多关于这些主题的内容,但我仍然不确定它是否能按预期工作。以及为什么。
我的理解:
- 在处理 Web 请求时,您正在使用其池中的 IIS 线程之一。在该请求中,例如,如果您使用异步调用从数据库中查询某些数据,您将释放该线程,以便 IIS 可以使用同一线程来处理另一个调用。那挺好的。可能。
- 稍后,当数据库最终提供等待的数据时,代码会继续执行。异步文档提到您现在可以在另一个线程中。或不。 DotNet 的决定。如果它和以前在同一个线程中,那没关系。
- 我使用依赖注入在 PerRequest 生命周期内注入和关闭上下文(使用 Microsoft Unity)。关闭是我主要关心的问题。它在我的同步世界中完美运行:dbcontext 在我的 Web 请求结束时关闭。
- 众所周知,EntityFramework 的 DbContext 不是线程安全的
问题 1:现在如果恢复代码在另一个线程中,它是来自同一个线程池 IIS 必须处理所有请求还是来自另一个边池?
问题 2:如果代码在另一个线程中运行,那么 WebRequest 上下文呢? DI 是否会正确跟踪延迟调用的结束,而不是在异步代码真正结束之前调用 Dispose()?
问题 3:如果我使用 EntityFramework 的异步方法,例如 ToListAsync 或 FirstOrDefaultAsync,我到处都读到“应该没问题”。有人可以详细说明吗? EF 是否专门跟踪 Web 请求或初始线程?是否发生了某种捕获?我的 dbcontext 是否会与另一个重用我的初始线程的 Web 请求混淆?
问题 4:如果我使用 EntityFramework 的普通(同步)方法但包装在一个任务中。会发生什么?还是“应该没问题”吗?
抱歉,问题太多了,困扰我很久了。
【问题讨论】:
-
你说的是 asp.net core 还是旧版本的 asp.net?
-
旧版本。假设我们在 4.7 版本中。它真的有影响吗?
-
这个问题太复杂(太长),无法正确回答。但要点是,即使请求在线程之间切换,asp.net(从 asp.net 4.5 开始)将能够跟踪(通过其 SynchronizationContext)并且每个线程都将具有正确的 http 上下文,该上下文将从一个线程流出给另一个。线程切换后请求不会结束。至于 EF 和线程安全 - 如果你一次从一个线程使用它(即使有多个线程,但在任何给定时间只有一个线程使用它) - 你很好。
-
但如果您要执行
var t1 = Task.Run(() => use context here);var t2 = Task.Run(() => again use context);await Task.WhenAll(t1, t2)之类的操作,那么您可能会遇到麻烦,因为您可能会同时从多个线程访问上下文。所以你只需要知道 request 和 thread 是不一样的。一个请求可能由不同的线程处理(至少在非高级版本的 asp.net 中)。 -
你的回答改变了一切。使用这个新的 SynchronizedContext 关键字,我能够更好地了解整个情况。现在我觉得自己很愚蠢。所以我会试着回答我自己的问题。
标签: c# asp.net multithreading entity-framework asynchronous