【发布时间】:2019-09-18 17:24:56
【问题描述】:
抱歉,这是一个有点冗长的设置/问题。我目前正在使用 C# ASP.NET Core 2.1 开发 API。我有一个 POST 端点,执行大约需要 5-10 秒(这很好)。我需要添加可能需要大量时间才能执行的功能。我当前的负载测试需要额外的 3 分钟。老实说,制作可能需要更长的时间,因为我无法真正得到一个很好的答案,即我们可以预期需要处理多少这些东西。从 UX 的角度来看,等待这么久是不可接受的,因为前端正在等待现有 POST 请求的结果。为了保持可接受的用户体验。
使用默认的 ASP.NET Core DI 容器将所有服务设置为瞬态。此应用程序使用 EF Core,并以与服务相同的方式设置(抱歉,我现在不在工作,忘记了设置文件中的确切用语)。
我首先尝试只创建一个后台工作人员,但是在将响应发送到客户端后,内部对象将开始被释放(即实体数据库上下文),并且在继续尝试使用所述执行代码时最终会抛出错误上下文(这是有道理的,因为它们被处置了)。
通过使用注入的 IServiceScopeFactory(默认 ASP.NET Core 实现),我能够让后台工作人员主要工作。我的所有代码都成功执行,直到我尝试保存到数据库。我们重写了 SaveChangesAsync() 方法,以便它会自动将属性 CreatedByName、CreatedTimestamp、UpdateByName 和 UpdatedTimestamp 分别更新为当前跟踪的实体。由于此逻辑由从 IServiceScopeFactory 创建的对象使用,因此它似乎不共享相同的 HttpContext,因此不会正确更新 CreatedByName 和 UpdatedByName(尝试将它们设置为 null,但 DB 列不接受 null) .
就在我下班之前,我创造了一个似乎可以工作,但看起来很脏的东西。我没有在后台工作人员中使用 IServiceScopeFactory 来创建新范围,而是使用指向当前正在执行的同一 API 中的端点的 WebClient 对象创建了一个模拟请求。这确实允许及时将响应发送回客户端,并且确实继续在服务器上执行新功能(正确更新我的实体)。
对不起,我现在不在工作,暂时无法提供代码示例,但如果需要为了完整回答这个帖子,我会在稍后放一些。
理想情况下,我希望能够启动我的请求,处理现有 POST 中的逻辑,将响应发送回客户端,并使用相同的上下文(包括包含身份信息的 HttpContext )。我的问题是,这可以在不创建模拟请求的情况下完成吗?这可以通过使用与原始线程相同的上下文的后台工作人员来完成(我知道这听起来有点奇怪)?他们是我完全想念的另一种方法吗?提前谢谢。
【问题讨论】:
标签: c# asp.net-core dependency-injection active-directory backgroundworker