【问题标题】:Removing Elements from BlockingCollection and populating Observable Collection从 BlockingCollection 中移除元素并填充 Observable 集合
【发布时间】:2013-07-10 20:46:48
【问题描述】:

我有一个用例,我想从阻塞集合(较大的图片是生产者消费者队列)中插入和删除自定义对象(股票)。

问题陈述与此线程完全相同 - update an ObservableCollection with a BlockingCollection

我不想使用响应式扩展,但希望使用传统的 C# 方式来执行此逻辑(不幸的是,这是一个硬性要求,并且完全理解其含义)。我的sn-p代码在这里

MainWindowViewModel.cs

public class MainWindow_VM : ViewModelBase
{
    public ObservableCollection<StockModel> stocks { get; set; }
    private readonly Dispatcher currentDispatcher;
    private BlockingCollection<StockModel> tasks = new BlockingCollection<StockModel>();
    #endregion

// All other standard ViewModel logic - Constructor, Command etc

    private void handlermethod(object sender, MarketDataEventArgs e)
    {
        Task.Factory.StartNew(AddUpdateObservableCollection);

        // Below thought process (maybe wrong) - How do i add the value to the BlockingCollection through a thread considering I have a ProducerConsumer class standard implementation (which has Enqueue and Dequeue Methods)
        using (ProducerConsumerQueue q = new ProducerConsumerQueue())
        {
              foreach (Stock s in e.updatedstock)
              {
                  StockModel sm = new StockModel();
                  sm.Symbol = s.Symbol;
                  sm.Bidprice = s.Bidprice;

                  q.EnqueueTask(s); 
               }
    }

    private void AddUpdateObservableCollection()
    {
        //Signalling mechanism still missing - when Stock comes into BlockingCollection - then this will start draining.
       // Also have to take care of Dispatcher stuff since you can only update ObservableCollection through Dispatcher

        foreach (StockModel sm in tasks)
        {
            if (sm != null)
            {
                if (stocks.Any(x => x.Symbol == sm.Symbol))
                {
                    var found = stocks.FirstOrDefault(x => x.Symbol == sm.Symbol);
                    int i = stocks.IndexOf(found);
                    stocks[i] = sm;
                }
                else
                {
                    stocks.Add(sm);
                }
            }
        }
    }
}

【问题讨论】:

  • 您从 BlockingCollection 添加和获取。

标签: c# wpf observablecollection blockingcollection


【解决方案1】:

看起来问题在于您的AddUpdateObservableCollection 方法看到tasks 集合为空,然后退出。

如果您希望它持久,请将您的 foreach 替换为:

foreach (StockModel sm in tasks.GetConsumingEnumerable())

您从GetConsumingEnumerable 获得的枚举器将阻塞等待要添加到队列的项目,并将继续阻塞,直到另一个线程将集合标记为完成添加。因此,当您完成向队列中添加内容并希望退出AddUpdateObservableCollection 方法时,只需调用tasks.CompleteAdding()。循环将清空队列,看到没有更多的项目即将到来(因为IsAddingCompleted 属性是true),然后退出。

不过,我对您如何将内容放入阻塞集合中有些困惑。您的代码 sn-p 不太清楚。如果您遇到问题,请编辑您的问题并解释问题所在。 handlermethod 代码中的注释非常神秘。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多