我在需要时使用依赖注入(inject)来访问我的服务,但我现在想创建一个并发任务,但是由于依赖注入(inject)对象及其生命周期,这会导致问题。
我读过这篇文章(标题:防止多线程):Link 由此,我了解到这是不可能的。
我的目标是让客户端发送一个请求来开始一个可能需要比客户端的连接超时时间更长的工作,因此我想要一个端点来启动一个任务并返回任务是否成功的状态开始了。
问题在于,因为数据库上下文和其他服务是在请求线程内的 Controller 上创建的,所以当您将该对象传递到新任务并结束旧任务时,由于以下事实,对象将被释放它们是在上述线程上创建的。
我知道对于数据库上下文,您可以注入(inject)数据库工厂接口(interface)并创建一个新实例,但这对非数据库对象没有帮助。 (我还读到创建自己的服务实例会破坏依赖注入(inject)点)。
有没有办法在新线程/任务上创建注入(inject)依赖项的新实例,或者完全避免这个问题?谢谢。
最佳答案
create a concurrent task but this is causing issues due to dependency injected objects and their lifetimes.
每次你分拆一个后台线程,或者一个可能在不同线程上并行运行的任务,你需要做的第一件事就是从容器中请求你想要使用的服务。这样容器就可以根据对象的生命周期确定需要构建哪些对象。 将依赖项从一个线程移动到另一个并行运行的线程是一种罪过。
看看 following information了解如何在多线程应用程序中使用 DI。编写信息时考虑了特定的 DI 容器,但其中大部分适用于一般的 DI。
在您的情况下,您希望将请求的数据转发到能够启动新线程、创建新范围、从该范围解析真实处理程序并调用它的类。你可以在 this answer 中看到非常相似的东西.
or avoid this problem completely?
您应该只在后台线程上分拆操作,以防您不关心它们是成功还是失败。然而,在大多数业务交易中,当操作失败时,您希望将此通知用户让他知道他必须重试,或者您希望代表他自动重试操作。如果您只是在后台线程上分拆操作,则很难可靠地实现这一点。
更好的解决方案是使用持久排队机制。这可以是数据库队列或消息队列。此类技术可确保操作不会丢失,并且通常具有内置的重试机制。看一下运行在 RabbitMq、MSMQ 或 SQL Server 之上的 MassTransit 或 NServiceBus 实例。
关于c# - 新任务中使用的依赖注入(inject)服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45162600/