首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多个长时间运行的IHostedSerivces或BackgroundService实现

多个长时间运行的IHostedSerivces或BackgroundService实现
EN

Stack Overflow用户
提问于 2018-10-17 21:28:30
回答 1查看 2.1K关注 0票数 4

在这个问题上我似乎找不到太多。我遇到的问题是,我需要运行2+长时间运行的后台服务,但只执行第一个注册服务的ExecuteAsync。我尝试过通过BackgroundService实现它并将代码放入ExecuteAsync,我还尝试直接实现IHostedService并将长时间运行的代码放入StartAsync中。

我认为问题是返回Task.CompletedTask;从未被调用。例如,我有两个实现为BackgroundServices的Kafka消费者,除了主题和OnMessage方法之外,代码看起来都是一样的

代码语言:javascript
复制
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
    var kafkaEndpoint = _kafkaConfig.Endpoint;

    var kafkaTopic = "PhoenixEventStore";

    var consumerConfig = new Dictionary<string, object>
    {
        { "group.id", "consumer1" },
        { "bootstrap.servers", kafkaEndpoint },
        { "auto.offset.reset", "earliest" }
    };

    using (var consumer = new Consumer<Null, string>(consumerConfig, null, new StringDeserializer(Encoding.UTF8)))
    {
        consumer.OnMessage += (obj, msg) =>
        {
            Log.Information($"Consumer1 Received {msg.Value}");
        };

        consumer.OnPartitionEOF += (_, end) =>
        {
            Log.Information($"Consumer1 Reached end of topic {end.Topic} partition {end.Partition}.");
        };

        consumer.OnError += (_, error) =>
        {
            Log.Error($"Consumer1 Error: {error}");
        };

        consumer.Subscribe(new List<string>() { kafkaTopic });

        while (!stoppingToken.IsCancellationRequested)
        {
            consumer.Poll(TimeSpan.FromSeconds(10));
        }

        //consider setting value that check whether the consumer has stopped polling.
    }
    return Task.CompletedTask;
}

因为这两个服务都是长期运行的,所以Task.Complete永远不会命中。但是,如果我注释掉while循环,两个服务的ExecuteAsync都会命中,而不仅仅是第一个注册的服务。

我已经找到了一个似乎有效的变通方法,但我想知道是否有人有更好的方法。

基本上,我重构了代码,让长时间运行的代码在一个名为StartConsumer的空方法中运行,然后让我的ExecuteAsync看起来像这样

代码语言:javascript
复制
  protected override Task ExecuteAsync(CancellationToken stoppingToken)
  {
        Task.Run(() => StartConsumer(stoppingToken));
        return Task.CompletedTask;
  }

这两个服务都是使用

代码语言:javascript
复制
services.AddHostedService<MyHostedService1>
services.AddHostedService<MyHostedService2>
EN

回答 1

Stack Overflow用户

发布于 2021-01-26 17:49:52

我也有同样的案例,而且它起作用了。模板是

代码语言:javascript
复制
 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                await Foo()
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message, exception: ex);
            }

            await Task.Delay(timeInMlSeconds);
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52856109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档