2014-01-17 89 views
3

假設BlockingCollection使用下面的ConcurrentQueue,如果您使用Timeout.Infinite,TryTake(T, Int32) method何時會返回false?什麼時候可以BlockingCollection <T> TryTake()返回false?

+2

您鏈接到的文檔包含您的問題的答案。你在尋找答案?一個具體的例子?會失敗的代碼?文檔清楚地說明將導致該方法拋出的原因。 – evanmcdonnal

+2

或者,您是在問什麼時候它會返回false而不是拋出異常? –

+0

@ledbutter這就是我所問的,我已經更新了OP。 – Gyrien

回答

7

下面是一個簡單的例子,顯示何時可以返回false:當收集被標記爲CompleteAdding,併成爲emptу

//by default, BlockingCollection will use ConcurrentQueue 
BlockingCollection<int> coll = new BlockingCollection<int>(); 

coll.Add(1); 
coll.Add(2); 
coll.CompleteAdding(); 

int item; 

if (coll.TryTake(out item, -1)) 
{ 
    Console.WriteLine(item); 
} 

if (coll.TryTake(out item, -1)) 
{ 
    Console.WriteLine(item); 
} 

if (coll.TryTake(out item, -1)) 
{ 
    //this won't get hit 
} 
else 
{ 
    Console.WriteLine("TryTake returned false!"); 
} 

這可以讓你以禁止將在隊列中,其餘元素的完整加工新項目

+0

如果不使用.CompleteAdding()觸發,它將不會返回false,但是正確嗎? – Gyrien

+1

@Gyrien正確,但它永遠不會超過最後一次'TryTake'調用(假設您使用無限超時),因爲它將在那裏等待,直到您發出信號表示您已完成添加到集合。 –

5

這將打印false

var coll = new BlockingCollection<int>();    

coll.CompleteAdding(); // closed for business 

int v; 
bool result = coll.TryTake(out v, Timeout.Infinite); 

Console.WriteLine(result); 

所以基本上一個BlockingCollection支持2個分隔符電子概念:空的和封閉的。雖然TryTake()可以在空隊列上永久等待,但當隊列都爲空已關閉時,將返回false

+0

如果您不使用.CompleteAdding()觸發,它將不會返回false,但是正確嗎? – Gyrien

+1

正確,它們旨在一起工作。 –

相關問題