Rx队列实现和Dispatcher的缓冲区

时间:2012-07-02 11:00:42

标签: system.reactive

我想实现一个队列,它能够从多个线程中的多个生成器中获取事件/项目,并在单个线程上使用它们。 这个队列可以在一些关键的环境中工作,所以我非常关心它的稳定性。

我使用Rx功能实现了它,但我有两个问题:

  1. 这个实现好吗?或者它可能以某种我不知道的方式存在缺陷? (作为替代方案 - 使用队列和锁定的手动实现)
  2. 什么是Dispatcher的缓冲区长度?它可以处理100k排队的物品吗?
  3. 以下代码使用简单的TestMethod说明了我的方法。它的输出显示所有值都来自不同的线程,但是在另一个线程上处理。

    [TestMethod()]
    public void RxTest()
    {
        Subject<string> queue = new Subject<string>();
    
        queue
            .ObserveOnDispatcher()
            .Subscribe(s =>
                            {
                                Debug.WriteLine("Value: {0}, Observed on ThreadId: {1}", s, Thread.CurrentThread.ManagedThreadId);
                            },
                        () => Dispatcher.CurrentDispatcher.InvokeShutdown());
    
        for (int j = 0; j < 10; j++)
        {
            ThreadPool.QueueUserWorkItem(o =>
            {
                for (int i = 0; i < 100; i++)
                {
                    Thread.Sleep(10);
                    queue.OnNext(string.Format("value: {0}, from thread: {1}", i.ToString(), Thread.CurrentThread.ManagedThreadId));
                }
                queue.OnCompleted();
            });
        }
    
    
        Dispatcher.Run();
    }
    

2 个答案:

答案 0 :(得分:4)

我不确定Subject在严重多线程场景中的行为。我可以想象,在你谈论的情况下,像BlockingCollection(及其潜在的ConcurrentQueue)这样的东西已经很好了。并且很容易启动。

var queue = new BlockingCollection<long>();

// subscribing
queue.GetConsumingEnumerable()
     .ToObservable(Scheduler.NewThread)
     .Subscribe(i => Debug.WriteLine("Value: {0}, Observed on ThreadId: {1}", i, Thread.CurrentThread.ManagedThreadId));

// sending
Observable.Interval(TimeSpan.FromMilliseconds(500), Scheduler.ThreadPool)
          .Do(i => Debug.WriteLine("Value: {0}, Sent on ThreadId: {1}", i, Thread.CurrentThread.ManagedThreadId))
          .Subscribe(i => queue.Add(i));

你当然不想接触队列和锁。 ConcurrentQueue实现非常出色,并且肯定能够有效地处理您正在讨论的大小队列。

答案 1 :(得分:3)

看看EventLoopScheduler。它内置于RX,我认为它可以做你想要的一切。

你可以使用任意数量的observable,调用.ObserveOn(els)els是你的EventLoopScheduler的实例),你现在正在将多个observable从多个线程编组到一个线程上将每个来电排队等候OnNext