2015-11-22 136 views
0

我從庫函數接收阻塞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) 
+0

https://msdn.microsoft.com/en-us/library/dd267317(v = vs.110).aspx BlockingCollection .ToArray可能工作但不確定,所以只有一條評論 – Paparazzi

+0

'consumer'變量的類型是什麼? –

+0

唉,ToArray()等待這個永無止境的結局。 –

回答

0

解決方法

因此,我們有無限的IEnumerable。如果裏面沒有信息,「foreach」會等待它們的出現。幸運的是,我們的「消費」方法接受取消令牌,我們可以在循環內更改它。從IEnumerable處理完第一條消息後,我設置了「CancelAfter(1000)」 - 類似於超時。如果新消息一秒鐘內出現,計時器將重置。當隊列爲空時,計時器火災,我們打破循環(嘗試...需要捕捉的OperationCanceledException)

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

您能否解釋*您的解決方法是如何工作的?這將使OP和其他人能夠在其他地方瞭解和應用您的解決方法(適用時)。 - [審查期間](http://stackoverflow.com/review/low-quality-posts/10301388) –

+1

我已編輯說明 –

0

我會將問題進一步抽象出來。我個人不會在循環數據時執行消耗。我將實現一個線程計時器,該計時器已入隊到堆棧或隊列。然後讓你的循環流行項目進行處理。您甚至可能會發現您想要使用ConcurrentQueue來處理波動。