Tôi có hai đối tượng BlockingCollection<T>
, collection1
và collection2
. Tôi muốn tiêu thụ các mặt hàng từ các bộ sưu tập này ưu tiên cho các mục trong số collection1
. Tức là, nếu cả hai bộ sưu tập đều có các mục, tôi muốn lấy các mục từ số collection1
trước. Nếu không có mục nào trong số chúng có mục, tôi muốn chờ một mục có sẵn.Làm cách nào để lấy một mục từ bất kỳ hai BlockingCollections nào có ưu tiên cho bộ sưu tập đầu tiên?
Tôi có đoạn mã sau:
public static T Take<T>(
BlockingCollection<T> collection1,
BlockingCollection<T> collection2) where T:class
{
if (collection1.TryTake(out var item1))
{
return item1;
}
T item2;
try
{
BlockingCollection<T>.TakeFromAny(
new[] { collection1, collection2 },
out item2);
}
catch (ArgumentException)
{
return null;
}
return item2;
}
Mã này được dự kiến sẽ trở null
khi CompleteAdding
được gọi trên cả hai bộ sưu tập và cả hai đều là những sản phẩm nào.
vấn đề chính của tôi với mã này là tài liệu cho các phương pháp TakeFromAny
xác định rằng TakeFromAny
sẽ ném một ArgumentException
nếu CompleteAdding
được gọi vào "bộ sưu tập":
ArgumentException
Đối số bộ sưu tập là một mảng có độ dài 0 hoặc chứa một phần tử null hoặc CompleteAdding() đã được gọi trên bộ sưu tập.
Nó có ném nếu CompleteAdding
được gọi trên bộ sưu tập nào không? hoặc cả hai bộ sưu tập?
Điều gì xảy ra nếu CompleteAdding
được gọi và bộ sưu tập vẫn có một số mục, nó có bị ném không?
Tôi cần một cách đáng tin cậy để thực hiện việc này.
Trong mã này tôi đang cố gắng để có được từ collection1
đầu tiên bởi vì tài liệu của TakeFromAny
không đưa ra bất cứ đảm bảo về trật tự bộ sưu tập mà từ đó để có những item nếu hai bộ sưu tập có các mục.
Điều này cũng có nghĩa là nếu cả hai bộ sưu tập đều trống và sau đó chúng nhận được các mục cùng một lúc sau đó, thì tôi có thể nhận được một mặt hàng từ collection2
trước.
EDIT:
Lý do tôi thêm các mục vào hai bộ sưu tập (và không chỉ đơn giản là một bộ sưu tập duy nhất) là bộ sưu tập đầu tiên không có một bộ sưu tập trên bên bị ràng buộc, và lần thứ hai không.
Thêm các chi tiết cho những ai quan tâm đến lý do tại sao tôi cần điều này:
Tôi đang sử dụng này trong một dự án mã nguồn mở được gọi là ProceduralDataflow. Xem tại đây để biết thêm chi tiết https://github.com/ymassad/ProceduralDataflow
Mỗi nút xử lý trong hệ thống dataflow có hai bộ sưu tập, một bộ sưu tập sẽ chứa các mục lần đầu tiên (vì vậy tôi cần làm chậm nhà sản xuất nếu cần) và bộ sưu tập khác sẽ chứa các mục đến lần thứ hai (hoặc thứ ba, ..) (do kết quả của vòng lặp trong luồng dữ liệu).
Lý do tại sao một bộ sưu tập không có giới hạn trên là tôi không muốn có deadlocks do kết quả của vòng lặp trong luồng dữ liệu.
Cảm ơn. Nó có ý nghĩa rằng nó hoạt động theo cách này, nhưng tài liệu không rõ ràng. Trong phương thức 'TryTakeFromAnyCoreSlow', điều kiện thứ 5 cho biết" được đánh dấu là đã hoàn thành ". Tôi cho rằng điều này có nghĩa là 'CompleteAdding' được gọi và bộ sưu tập không trống. Tôi đã làm theo các mã để phương pháp 'GetHandles' và tôi nghĩ rằng đây là trường hợp. –
Tôi đã hy vọng rằng có một số tài liệu trên MSDN để làm rõ tất cả điều này. –
Thật vậy. Về cơ bản, ['IsCompleted'] (https://msdn.microsoft.com/en-us/library/dd267315 (v = vs.110) .aspx) property - * Cho dù bộ sưu tập này đã được đánh dấu là hoàn chỉnh để thêm và là trống. * –