C# 如何在另一个线程填充IEnumerable时枚举该IEnumerable
我希望在同一台机器上有两个线程,一个用于填充集合,另一个用于在数据可用时立即从中弹出数据,并在知道结束时停止。 我只是不知道该用什么收藏C# 如何在另一个线程填充IEnumerable时枚举该IEnumerable,c#,multithreading,collections,thread-safety,C#,Multithreading,Collections,Thread Safety,我希望在同一台机器上有两个线程,一个用于填充集合,另一个用于在数据可用时立即从中弹出数据,并在知道结束时停止。 我只是不知道该用什么收藏 private void DataProviderThread() { GlobalCollection = new SomeMagicCollection(); for (int i = 0; i < 100; i++) { GlobalCollection.Add(new SomeDataItem(i));
private void DataProviderThread()
{
GlobalCollection = new SomeMagicCollection();
for (int i = 0; i < 100; i++)
{
GlobalCollection.Add(new SomeDataItem(i));
Thread.Sleep(100);
}
GlobalCollection.IHaveFinishedPopulatingThanksAndBye();
}
private void DataCruncherThread()
{
foreach (var item in GlobalCollection)
{
// Do whatever
}
// The control should exit foreach only once the data provider states that the collection is finished
}
private void数据提供者线程()
{
GlobalCollection=新的SomeMagicCollection();
对于(int i=0;i<100;i++)
{
添加(新的SomeDataItem(i));
睡眠(100);
}
GlobalCollection.i已完成人口统计汉克和耶();
}
私有void DataCruncherThread()
{
foreach(GlobalCollection中的var项)
{
//做任何事
}
//只有在数据提供程序声明收集已完成时,该控件才应退出foreach
}
然后,我想简单地对它进行迭代,让集合负责
- 保持线程安全
- 授予标准IEnumerable功能
- 让我的data cruncher线程等待新项目,直到DataBuilder明确调用了
,然后干净地退出循环i完成了populationtHanksandYe()
- 允许我让其他几个线程使用相同的约束进行迭代
我不敢相信C#没有在新版本中发布这个。但是它的名字是什么?你拥有的是一个经典的生产者/消费者模式 您可以使用
ConcurrentQueue
或者更好的方法是使用
BoundedCapacity属性允许您调节(调节)数据流
它是一个
IEnumerable
,但不要试图像非共享集合那样使用它。TryTake()
方法是获取数据最有用的方法 ConcurrentQueue可能重复:使用它作为IEnumerable
访问数据是一种非常好的方法,或者如果情况允许,使用它作为GetConsumineumerable
。我发现我很少需要使用Take
或TryTake`,因为这两个选项都是为了在从其他线程修改集合时使用。对于某些类型的操作,只要知道并发性,使用IEnumerable接口是可以的。我不认为消费者可以很清楚地使用,但这是一个品味的问题。你不认为它很清楚与它不起作用有很大的不同。这两个操作在很大程度上都是为在多线程上下文中使用而设计的。