【问题标题】:Run processing in separated thread by group按组在单独的线程中运行处理
【发布时间】:2020-02-03 17:55:05
【问题描述】:

我正在尝试在我的 Kafka 消费者中使用 Rx。

public static event EventHandler<ConsumeResult<string, string>> GenericEvent;

然后我有以下代码

var observable = Observable.FromEventPattern<ConsumeResult<string, string>>(
     x => GenericEvent += x,
     x => GenericEvent -= x)
  .Select(x => x.EventArgs);

while (!cancellationToken.IsCancellationRequested)
{
    ConsumeResult<string, string> consumeResult = _consumer.Consume(cancellationToken);
    GenericEvent(consumeResult.Topic, consumeResult);
}

然后我在某处使用它

var subscription = observable.Subscribe(message =>
{
    Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} ** {message.Topic}/{message.Partition} @{message.Offset}: '{message.Value}'");

    //_kafkaConsumer.Commit(messages);
});

是否有可能按主题名称(consumeResult.Topic)运行单独的线程?消费者收到消息后,按主题将消息重定向到对应的线程

【问题讨论】:

    标签: c# asynchronous async-await system.reactive rx.net


    【解决方案1】:

    试一试:

    Observable
        .Interval(TimeSpan.FromSeconds(0.1))
        .Take(20)
        .GroupBy(x => x % 3)
        .SelectMany(xs => Observable.Using(() => new EventLoopScheduler(), els => xs.ObserveOn(els)))
        .Subscribe(x => Console.WriteLine($"{x} {Thread.CurrentThread.ManagedThreadId}"));
    

    这确保在new EventLoopScheduler() 调度程序中为GroupBy 运算符创建的每个内部可观察对象创建一个线程。 SelectMany 扁平化组,但保持EventLoopScheduler 与每个组相关联。

    在你的情况下,你 GroupBy consumeResult.Topic 属性。

    请确保您的源 observable 在线程永远存在之前结束。在订阅上调用 Dispose() 足以结束 observable。

    【讨论】:

    • 哇,你是超人!谢谢。您能否再解释一下“请确保您的源 observable 结束,因为线程永远存在,直到他们这样做”
    • @Chebur - Observable.Using(() =&gt; new EventLoopScheduler(), els =&gt; xs.ObserveOn(els)) 代码为每个 new EventLoopScheduler() 创建一个新线程。直到每个EventLoopScheduler 调用了Dispose(),这些线程才会退出。当外部可观察对象完成时,就会发生这种情况。在我的示例中,我使用Take(20) 使其在20 元素之后自然停止,但如果您没有自然结束,那么您需要处理订阅以使其结束并且允许新线程自然退出。
    • 谢谢。我如何在订阅方法中使用 ConsumeResult&lt;string, string&gt; 的值?看来我需要一些逻辑而不是 Console.WriteLine,对吗?或者处理逻辑应该在其他地方?
    • 哦,我找到了,是x.EventArgs
    • @Chebur - 你还没有解释你在用你的代码做什么,所以很难说什么是正确的,但你可以选择使用.Select.Do.Subscribe 进行处理。
    猜你喜欢
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2019-08-12
    • 1970-01-01
    • 2017-12-13
    • 2012-05-20
    相关资源
    最近更新 更多