Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从BlockingCollection中删除元素并填充可观察集合_C#_Wpf_Observablecollection_Blockingcollection - Fatal编程技术网

C# 从BlockingCollection中删除元素并填充可观察集合

C# 从BlockingCollection中删除元素并填充可观察集合,c#,wpf,observablecollection,blockingcollection,C#,Wpf,Observablecollection,Blockingcollection,我有一个用例,在这个用例中,我想从阻塞集合(更大的图片是生产者-消费者队列)中插入和删除自定义对象(库存) 问题陈述与此线程非常相似- 我不想使用反应式扩展,但希望使用传统的C#方式来实现这一逻辑(不幸的是,这是一个很难满足的要求,并且完全理解其含义)。我的代码片段在这里 MainWindowViewModel.cs public class MainWindow_VM : ViewModelBase { public ObservableCollection<StockModel

我有一个用例,在这个用例中,我想从阻塞集合(更大的图片是生产者-消费者队列)中插入和删除自定义对象(库存)

问题陈述与此线程非常相似-

我不想使用反应式扩展,但希望使用传统的C#方式来实现这一逻辑(不幸的是,这是一个很难满足的要求,并且完全理解其含义)。我的代码片段在这里

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);
                }
            }
        }
    }
}
public类主窗口\u VM:ViewModelBase
{
公共可观测集合库存{get;set;}
专用只读调度器currentDispatcher;
私有BlockingCollection任务=新建BlockingCollection();
#端区
//所有其他标准ViewModel逻辑-构造函数、命令等
私有void handlermethod(对象发送方,MarketDataEventArgs e)
{
Task.Factory.StartNew(AddUpdateObservableCollection);
//下面的思考过程(可能是错误的)-考虑到我有一个ProducerConsumer类标准实现(具有排队和退队方法),如何通过线程向BlockingCollection添加值
使用(ProducerConsumerQueue q=new ProducerConsumerQueue())
{
foreach(e.updatedstock中的库存)
{
StockModel sm=新的StockModel();
sm.Symbol=s.Symbol;
sm.Bidprice=s.Bidprice;
q、 使任务排队;
}
}
私有void AddUpdateObservableCollection()
{
//信号机制仍然缺失——当库存进入BlockingCollection时——那么这将开始消耗。
//还必须处理Dispatcher的事情,因为您只能通过Dispatcher更新ObservableCollection
foreach(任务中的库存模型sm)
{
如果(sm!=null)
{
if(stocks.Any(x=>x.Symbol==sm.Symbol))
{
var found=stocks.FirstOrDefault(x=>x.Symbol==sm.Symbol);
int i=股票指数(已发现);
股票[i]=sm;
}
其他的
{
股票。加(sm);
}
}
}
}
}

问题似乎在于
AddUpdateObservableCollection
方法发现
tasks
集合为空,然后退出

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

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


不过,我对您如何将内容放入blocking collection有点困惑。您的代码片段不太清楚。如果您在这方面遇到问题,请编辑您的问题并解释问题所在。
handlermethod
的代码中的注释非常模糊。

您添加了BlockingCollection并从中获取了内容。谢谢Jim。我正在使用Pub/Sub将数据导入我的处理程序。请参阅我在此处发布的图表-