从BlockingCollection中删除元素并填充Observable Collection
本文关键字:填充 Observable Collection 元素 BlockingCollection 删除 | 更新日期: 2023-09-27 18:22:02
我有一个用例,其中我想从阻塞集合中插入和删除自定义对象(Stocks)(较大的图片是生产者-消费者队列)。
问题语句与此线程完全相似-使用BlockingCollection 更新ObservableCollection
我不想使用反应式扩展,但希望使用传统的C#方式来实现这一逻辑(不幸的是,这是一个很难的要求,并且完全理解其含义)。我的代码片段在这里
主窗口视图Model.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);
}
}
}
}
}
问题似乎是AddUpdateObservableCollection
方法发现tasks
集合为空,然后退出。
如果您希望它是持久的,请将foreach
替换为:
foreach (StockModel sm in tasks.GetConsumingEnumerable())
从GetConsumingEnumerable获得的枚举器将阻止等待要添加到队列的项,并将继续阻止,直到其他线程将集合标记为完成添加。因此,当您向队列添加完内容并希望AddUpdateObservableCollection
方法退出时,只需调用tasks.CompleteAdding()
即可。循环将清空队列,查看没有更多的项目(因为IsAddingCompleted
属性是true
),然后退出。
不过,我有点困惑于你是如何将东西放入阻塞集合的。您的代码片段不太清楚。如果你有问题,请编辑你的问题并解释问题所在。handlermethod
代码中的注释非常神秘。