【问题标题】:Issue adding more than one hosted service添加多个托管服务的问题
【发布时间】:2021-10-01 15:29:59
【问题描述】:

我遇到了一个小问题,需要一些帮助。我尝试将 2 个托管服务添加到我的 Blazor Server 应用程序中。这些都是长期运行的后台服务,它们创建 websocket 连接并保持它们打开以接收数据。问题是只有第一个服务正在启动。第二个服务确实启动了,但只是在我关闭应用程序时短暂启动,并且在最后一秒有几条日志消息短暂闪烁。这两个服务都有 StartAsync 和 StopAsync。

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        })
        .ConfigureServices(services =>
        {
            services.AddHostedService<Service1>();
            services.AddSingleton<Service1>(p => p.GetServices<IHostedService>().OfType<Service1>().Single());
            services.AddHostedService<Service2>();
            services.AddSingleton<Service2>(p => p.GetServices<IHostedService>().OfType<Service2>().Single());
        });

不确定我在这里做错了什么,或者不可能同时运行 2 个服务?

感谢您的帮助!

编辑: 我正在使用 AddSingleton,因为我将实例注入到我的一些网页中,以便访问我在服务中设置的公共属性,以便可以在网页上显示数据。

服务很大,所以我不想粘贴所有代码。基本上它们的要点是:

public Task StartAsync(CancellationToken cancellationToken)
{
    //Connect to websocket streams and handle incoming data

    while (true)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            return Task.CompletedTask;
        }
    }
}

【问题讨论】:

  • 我们不能神奇地知道Service1和2在做什么,我们需要查看代码才能理解发生了什么。
  • 你为什么要添加带有services.AddSingleton 的单例? services.AddHostedService 一个人就够了
  • @CamiloTerevinto 抱歉,我认为没有必要将它们包括在内,因为我的问题更多是关于同时运行这两个服务,这似乎没有发生。
  • @abdusco 我将实例注入到我的一些 razor 页面中,以便访问公共属性以从服务中获取信息以显示在网页上。
  • 您需要为我们确认StartAsync方法是否及时返回。

标签: c# asp.net-core .net-core blazor blazor-server-side


【解决方案1】:

不支持while(true) {...} 模式。

您必须启动一个计时器、线程或长时间运行的任务。

StartAsync 必须快速返回,Services 是按顺序启动的。

这适用于多个服务:

    public Task StartAsync(CancellationToken cancellationToken)
    {
        Task.Run(Forever);  // dont pass the cancellationToken
        return Task.CompletedTask;
    }

    private async Task Forever()
    {
        while (true)
        {
            await Task.Delay(5_000);
        }
    }

    public async Task StopAsync(CancellationToken cancellationToken)
    {                    
    }

或者查找BackgroundService 基类。上面的哪个,但可能更好。

【讨论】:

  • 谢谢亨克!感谢帮助。如果您不介意,请跟进问题。我需要能够在网页中访问的服务/任务中的数据。目前解决方案是使用 AddSingleton,然后将服务实例注入网页,我可以访问从服务公开的公共属性,网页读取该数据。如果我将这些服务作为一项任务运行,我将无法以相同的方式访问该数据。关于如何实现这一目标的任何建议? Tldr:服务中的Websocket数据,需要一种方法来访问数据以显示在网页上。
  • 使用专用存储库。使用单例并将其注入到服务和页面中。确保它是线程安全的。
猜你喜欢
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-20
相关资源
最近更新 更多