2010-09-29 27 views
21

Tôi có hàng rào chặn bị chặn trong một ứng dụng được viết cách đây vài năm. Hãy chỉ nói rằng việc thực hiện ít hơn sao, nhưng nó hoạt động. Tuy nhiên, nó có một số vấn đề hiệu suất. Có vẻ như .NET 4.0 BlockingCollection<T> là sự thay thế phù hợp, nhưng tôi cần đảm bảo rằng nó thực sự là một hàng đợi. Nghĩa là, nó có được đảm bảo là đúng FIFO nếu được sử dụng trong một nhà sản xuất đơn lẻ, một người tiêu dùng không?BlockingCollection <T> có đảm bảo đơn hàng xóa không?

Tài liệu không nói cụ thể. Chủ đề BlockingCollection không nói (trong chú thích):

BlockingCollection<T> là tương tự như một truyền thống dữ liệu hàng đợi chặn cấu trúc, ngoại trừ việc cơ chế lưu trữ dữ liệu cơ bản là trừu tượng xôi như một IProducerConsumerCollection<T>.

Nhưng không có gì đặc biệt nói rằng mọi thứ sẽ bị xóa theo cùng thứ tự mà chúng được thêm vào.

Có ai biết chắc không?

+3

Downvoter, bạn có điều gì muốn nói không? Đó là phong tục để đưa ra một lý do cho một downvote. –

Trả lời

38

Vâng, BlockingCollection<T> thực sự được thiết kế cho công việc song song, nơi bạn có nhiều "nhà sản xuất" mô phỏng và một người tiêu dùng (sử dụng GetConsumingEnumerable()).

Trong trường hợp này, bạn không có cách nào để đảm bảo thứ tự chèn, do đó các ràng buộc đặt hàng không được chỉ định.

Điều đó đang được nói, BlockingCollection<T> hoạt động theo bất kỳ IProducerConsumerCollection<T> nào (được chỉ định trong hàm tạo). Nếu bạn không cung cấp một trong hàm tạo, trong nội bộ, nó sẽ sử dụng một ConcurrentQueue<T>. Điều này khiến nó trở thành FIFO, vì nó thực sự sẽ là một hàng đợi. Vì vậy, có, theo mặc định, nó sẽ được "đảm bảo để được đúng FIFO nếu được sử dụng trong một sản xuất đơn, người tiêu dùng duy nhất thời trang", ít nhất là trong việc thực hiện hiện tại. Nếu bạn muốn để lực lượng này cho chống tương lai (từ hàng đợi là một chi tiết thực hiện), chỉ cần xây dựng nó như:

var blockingCollection = new BlockingCollection<MyClass>(new ConcurrentQueue<MyClass>()); 

Điều đó sẽ đảm bảo rằng nó sử dụng một hàng đợi bây giờ, và trong tương lai (từ hàng đợi là chi tiết triển khai).

+1

Tôi không tin rằng sự tồn tại của 'GetConsumingEnumerable' ngụ ý rằng bộ sưu tập dành cho nhiều nhà sản xuất và một người tiêu dùng duy nhất. Cấp, rằng phương pháp cụ thể dường như được dành cho một người tiêu dùng duy nhất, nhưng điều đó chắc chắn không ngăn cản nhiều người tiêu dùng. –

+0

@Jim: Nó không - đó là động lực chính đằng sau đó. Nhiều người tiêu dùng đã được dự định thông qua AddToAny(), trong đó mỗi BlockingCollections có liên quan đã được sử dụng bởi một người tiêu dùng duy nhất.Sự kiện tên chính nó "BlockingCollection" cho thấy rằng nó "khối" (ở phía người tiêu dùng) cho đến khi các mục được thêm vào. –

+0

Bạn đã trả lời câu hỏi trực tiếp của tôi, ngăn tôi không phải tự mình IDASM. Cảm ơn. –

1

Có lẽ tài liệu MSDN đã được cập nhật kể từ câu hỏi này nhưng bây giờ rõ ràng nói rằng BlockingCollection sẽ mặc định thành FIFO trừ khi được hướng dẫn khác.

xem: https://msdn.microsoft.com/en-us/library/dd997371(v=vs.110).aspx hoặc trong trường hợp MS thay đổi liên kết google 'MSDN BlockingCollection Tổng quan'

NET Framework 4.6 và 4.5

Look cho 'Xác định Type Collection' trên trang đó.

Các vấn đề liên quan