新任务中使用的依赖项注入服务 [英] Dependency injected services used in a new task

查看:95
本文介绍了新任务中使用的依赖项注入服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在需要时使用依赖注入来访问我的服务,但是我现在想创建一个并发任务,但这由于依赖注入的对象及其生存期而引起问题.

I'm using dependency injection to access my services when needed but i'm now wanting to create a concurrent task but this is causing issues due to dependency injected objects and their lifetimes.

我已经阅读了这篇文章(标题:防止多线程):链接从那开始,我已经收集到这是不可能的.

I've read this article (Heading: Prevents multi-threading): Link And from that, I've gathered that this isn't possible.

我的目标是让客户端发送一个开始工作的请求,该请求可能花费比客户端的连接超时更长的时间,因此我想拥有一个可以启动任务并返回任务是否成功完成的状态的终结点开始.

My objective is to let the client send a request to begin a job that could take longer than the connection timeout of the client, thus I want to have an endpoint that initiates a task and returns the status of whether the task had successfully started.

问题在于,因为数据库上下文和其他服务是在请求的线程内的控制器上创建的,所以当您将该对象传递到新任务并结束旧任务时,由于以下事实而导致对象被处置:它们是在所述线程上创建的.

The problem is that because the database context and other services are created on the controller within the thread of the request, when you pass that object into a new task and end the old task, the objects are disposed due to the fact that they were created on said thread.

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

I'm aware that for a database context you can inject the database factory interface and create a new instance but this doesn't help me for the non database objects. (I've also read that creating your own service instances defeats the point of dependency injection).

有没有办法为新线程/任务创建注入的依赖项的新实例,还是完全避免此问题?谢谢.

Is there a way I can create a new instance of my injected dependencies on a new thread/task, or avoid this problem completely? Thanks.

推荐答案

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

create a concurrent task but this is causing issues due to dependency injected objects and their lifetimes.

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

Every time you spin off a background thread, or a task that can potentially run on a different thread in parallel, the first thing you need to do during that operation is request the service you wish to use from the container. This way the container can determine which objects need to be build depending on their lifestyles. Moving dependencies from one thread to another parallel-running thread is a sin.

看看以下信息,以了解如何在多线程化的应用程序.该信息是在考虑特定的DI容器的情况下编写的,但大多数信息通常适用于DI.

Take a look at the following information to understand how to work with DI in multi-threaded applications. The information is written with a particular DI container in mind, but most of it is applicable to DI in general.

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

In your case, you wish to forward data of a request to a class that is able to start a new thread, create a new scope, resolve the real handler from that scope and invoke it. You can see something very similar in this answer.

还是完全避免这个问题?

or avoid this problem completely?

您只应在后台线程上剥离操作,以防它们是否成功.但是,在大多数业务交易中,当操作失败时,您希望将其告知用户以使其知道他必须重试,或者您希望代表他自动重试该操作.如果仅在后台线程上剥离操作,很难可靠地实现这一点.

You should only spin off operations on a background thread in case you don't care whether they succeed or fail. In most business transactions however, when the operation fails, you wish to either inform the user about this to let him know he has to retry, or you want to retry the operation automatically on his behalf. This is very hard to achieve reliably in case you just spin off operations on a background thread.

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

A better solution would be to use a durable queuing mechanism. This can be a database queue or message queue. Such technology ensures that operations can't get lost and often have built-in retry mechanisms. Take a look at MassTransit or NServiceBus for instance that operateon top of RabbitMq, MSMQ or SQL Server.

这篇关于新任务中使用的依赖项注入服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆