【问题标题】:Multiple Hosted Services in Dotnet Core Windows ServiceDotnet Core Windows 服务中的多个托管服务
【发布时间】:2019-09-03 13:30:54
【问题描述】:

我有一个基于此示例的 netcore 2.0 的 Windows 服务: https://www.stevejgordon.co.uk/running-net-core-generic-host-applications-as-a-windows-service

在我的例子中,主要的托管服务订阅了一个消息队列并按顺序处理消息(每次出现新消息时队列 api 都会引发一个事件)。 如果任何消息无法处理,它们将被移至不同的队列以重试(x 次,具有指数回退)。所以这需要在单独的线程上完成,以免造成主队列处理的延迟

是否可以配置2个HostedServices:

var builder = new HostBuilder()
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<MyMsgProcessingService>();
                services.AddHostedService<MyRetryService>();
            });

这确实开始了,它确实命中了每个服务的StartAsync 方法(在IHostedService 接口上)

或者您是否只允许拥有(拥有)一个IHostedService 实现?

如果两个都可以,那么慢服务的工作会不会拖累主服务的工作?

如果只有一个,最好只启动另一个线程来完成重试队列的工作吗?我如何确保新线程在服务运行的整个过程中都存在? while 循环似乎不合适,因为我只是在等待引发事件

例如

public Task StartAsync(CancellationToken cancellationToken)
{
    Task t = Task.Run(() => ProcessRetrys(), cancellationToken);

【问题讨论】:

  • 有同样的问题,然后发现确认in the MS Docs在一个IHost下注册和托管多个服务是可以接受的。

标签: c# multithreading .net-core windows-services task


【解决方案1】:

或者您是否只允许拥有(拥有)一个 IHostedService 实现?

您可以拥有任意数量的。只要您可以接受这样一个事实,即如果进程出现故障,其中的所有内容(所有服务)也会出现故障。

要考虑的第二件事是线程池。线程池对所有服务都是通用的,因此如果其中一个服务需要线程,其他服务可能会受到影响。

如果两个都可以,慢服务的工作会不会拖累主服务的工作?

取决于一项服务是否等待另一项服务的数据。以及他们之间的沟通方式。如果是同步的,那么最慢的线程就是瓶颈。

我如何确保新线程在服务运行的整个过程中都存在?

创建一个前台线程。 AboutHow to configure. 但是您必须小心,并在应用关闭时优雅地终止此类线程,并在 StopAsync 方法调用中处理它。

while 循环似乎不合适,因为我只是在等待引发事件

使用非阻塞队列在服务之间进行通信。我不能给你一个具体实现的链接,因为它们很多,但你可以开始另一个问题来帮助你找到合适的。

【讨论】:

  • 谢谢。目前我有一个 HostedService,它有两个通过标准 IoC 注入的 QueueClient 包装器。每个都在等待从各自的队列(主要和重试)中引发事件。当消息进入主队列时,处理涉及异步的 db-access 和也是异步的 http 请求,如果失败则写入重试队列,这也是异步的。所以我希望所有操作都是异步的,这意味着在顶层注入的两个 queueClient 将不断地从同一个线程池中请求线程?
  • 我可以做些什么来优先处理主队列上的处理?
  • 猜猜我说的可能听起来像“只需获得两个线程池”。如果是这样,那我应该换个说法。一个线程池的问题是有 IO 线程和工作线程。 More info here。如果您有很多 IO 工作(在您的情况下是数据库访问和 http 请求),那么由于 IO 线程耗尽,这些工作可能会在某个时候受到限制,因此您将不会获得异步回调继续快速处理。
  • 你要做的是尽快离开IO线程,这意味着IO操作(DB/http)之后的继续应该工作很短的时间,可能会排队一些工作工作线程只需运行一个新任务。但这仅在您每秒有数千个新项目在队列中时才重要。如果线程数量不再增加并且传入消息的处理时间增加,您必须不时监视线程池和您的应用程序以注意到线程池饥饿。如果一次处理来自队列的新项目,那么无论如何您都可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多