2013-07-12 81 views
0

我正在使用類型爲T的類的BlockingCollection,我想知道是否應該將T轉換爲結構。阻止集合操作和結構

從原則上BlockingCollection簽名我不明白的問題是:

[DebuggerDisplay("Count = {Count}, Type = {m_collection}")] 
[ComVisible(false)] 
[DebuggerTypeProxy(typeof (SystemThreadingCollections_BlockingCollectionDebugView<>))] 
[HostProtection(SecurityAction.LinkDemand, ExternalThreading = true, Synchronization = true)] 
public class BlockingCollection<T> : IEnumerable<T>, ICollection, IEnumerable, IDisposable 

然而,語義阻塞操作的需要支持取消的是,如果一個元素變得可用之前,操作將被取消,則返回null 。這裏的問題是,一個結構不能爲空,所以下面的代碼是無效的

​​

因此被阻止限於類藏品,還是語義變化返回未初始化結構?

回答

2

根據documentationTake不返回null如果操作被取消:代之以拋出OperationCanceledException。隨意使用任何類型,並準備好在需要時處理異常。

0

這更多的是與結構vs類的行爲有關。不僅是一個類不能爲空,而且它也是通過值傳遞的,而不是通過引用。這意味着每次訪問集合的元素時,都會得到它的副本,而不是原始元素。

這對所有收藏都是一樣的,而不僅僅是阻擋收藏。

關於Take,如Julien所述,Take引發OperationCanceledException,它不會返回空值。如果你想使用Take,你將不得不處理異常,無論你使用Struct還是一個Class。

一個更好的選擇,特別是如果你期望頻繁取消cancellatins,是使用TryTake而不是Take並檢查結果。例如

Struct myStruct; 
if(collection.TryTake(out myStruct)) 
{ 
.... 
}