在新任务中使用的依赖注入服务

Kie*_*lin 7 c# multithreading dependency-injection asp.net-core

我正在使用依赖注入来在需要时访问我的服务,但我现在想要创建并发任务,但这会导致由于依赖注入对象及其生命周期引起的问题.

我已经阅读了这篇文章(标题:防止多线程):链接 从那以后,我发现这是不可能的.

我的目标是让客户端发送一个请求来开始一个可能需要比客户端的连接超时更长的工作,因此我希望有一个端点启动任务并返回任务是否已成功启动的状态.

问题是因为数据库上下文和其他服务是在请求的线程内的控制器上创建的,当您将该对象传递给新任务并结束旧任务时,对象会因为它们被创建而被处置在说的线程上.

我知道对于数据库上下文,您可以注入数据库工厂接口并创建一个新实例,但这对我的非数据库对象没有帮助.(我还读到创建自己的服务实例会破坏依赖注入点).

有没有办法可以在新线程/任务上创建注入依赖项的新实例,或者完全避免这个问题?谢谢.

Ste*_*ven 8

创建一个并发任务,但这会由于依赖注入的对象及其生命周期而导致问题。

每次分离后台线程或可能并行运行在不同线程上的任务时,您在该操作期间需要做的第一件事就是从容器请求您希望使用的服务。通过这种方式,容器可以根据他们的生活方式确定需要构建哪些对象。将依赖项从一个线程移动到另一个并行运行的线程是一种罪过。

查看以下信息以了解如何在多线程应用程序中使用 DI。这些信息是用特定的 DI 容器编写的,但大部分内容通常适用于 DI。

在您的情况下,您希望将请求的数据转发到能够启动新线程、创建新范围、从该范围解析实际处理程序并调用它的类。您可以在此答案中看到非常相似的内容。

或者完全避免这个问题?

您应该只在后台线程上分离操作,以防您不关心它们是成功还是失败。然而,在大多数业务事务中,当操作失败时,您希望通知用户这一点,让他知道他必须重试,或者您希望代表他自动重试操作。如果您只是在后台线程上分拆操作,则很难可靠地实现这一点。

更好的解决方案是使用持久的排队机制。这可以是数据库队列或消息队列。这种技术确保操作不会丢失,并且通常具有内置的重试机制。看看在 RabbitMq、MSMQ 或 SQL Server 上运行的 MassTransit 或 NServiceBus 为例。

  • “如果任务终止,则通知用户”。但是,如果 Web 服务在此后台操作过程中被回收、崩溃或服务器崩溃,该怎么办?这将导致用户得不到通知。持久排队是这个问题的_the_解决方案。 (3认同)