从阻止IEnumerable中读取

时间:2015-11-22 17:36:14

标签: c# .net ienumerable

我从库函数接收阻塞IEnumerable(如永不结束的流)。有时它包含一些消息,有时甚至包含很多消息。我需要从中获取所有现有消息,我不想等待新消息。

此代码获取现有消息并等待10秒超时。

var cancellationTokenSource = new CancellationTokenSource(10000);
foreach (var data in consumer.Consume(cancellationTokenSource.Token))
{
    Console.WriteLine(data.message);
}

我应该如何修改我的代码?

public IEnumerable<Message> Consume(CancellationToken? cancellationToken = null)

3 个答案:

答案 0 :(得分:0)

我会进一步提出问题。我个人在循环数据时不会执行消耗。我会实现一个排队到堆栈或队列的线程计时器。然后让你的循环Pop项目进行处理。你甚至可能会发现你想使用ConcurrentQueue来处理波动性。

答案 1 :(得分:0)

我认为BlockingCollection.TryTake会做你想要的事情

  

如果集合为空,则此方法立即返回false。

while (bc.TryTake(out T))
{
}

答案 2 :(得分:0)

解决方法

所以,我们有无限的IEnumerable。如果其中没有消息,“foreach”将等待它们的出现。幸运的是,我们的“Consume”方法接受一个取消令牌,我们可以在循环内更改它。在处理来自IEnumerable的第一条消息后,我设置了“CancelAfter(1000)” - 类似于超时。如果新消息出现,则计时器将重置。当队列为空时,计时器触发,我们打破循环(try ... catch需要OperationCanceledException)

var cancellationTokenSource = new CancellationTokenSource(1000);
foreach (var data in consumer.Consume(cancellationTokenSource.Token))
{
    Console.WriteLine(data.message);
    cancellationTokenSource.CancelAfter(1000);
}