Nếu bạn có Net 4.0 hoặc cao hơn, bạn có thể làm theo cách này bằng cách sử dụng một BlockingCollection
int maxBufferCap = 500;
BlockingCollection<MagicalObject> Collection
= new BlockingCollection<MagicalObject>(maxBufferCap);
void Producer()
{
while (magic.HasMoreMagic)
{
this.Collection.Add(magic.ProduceMagic());
}
this.Collection.CompleteAdding();
}
void Consumer()
{
foreach (MagicalObject magicalObject in this.Collection.GetConsumingEnumerable())
{
DoSomthing(magicalObject);
}
}
Dòng foreach
sẽ ngủ nếu không có dữ liệu trong bộ đệm, nó cũng sẽ tự động đánh thức nó khi một cái gì đó được thêm vào bộ sưu tập.
Lý do tôi đặt bộ đệm tối đa là nếu nhà sản xuất của bạn nhanh hơn nhiều so với người tiêu dùng bạn có thể sẽ tiêu tốn rất nhiều bộ nhớ khi ngày càng có nhiều đối tượng được đưa vào bộ sưu tập. Bằng cách thiết lập kích thước bộ đệm tối đa khi bạn tạo bộ sưu tập chặn khi kích thước bộ đệm đạt đến lệnh gọi Add
trên nhà sản xuất sẽ chặn cho đến khi một mục đã bị xóa khỏi bộ sưu tập của người tiêu dùng.
Một phần thưởng khác của lớp học BlockingCollection
là bạn có thể có nhiều nhà sản xuất và người tiêu dùng theo ý muốn, không cần tỷ lệ 1: 1. Nếu DoSomthing
hỗ trợ nó, bạn có thể có một vòng lặp foreach
mỗi lõi của máy tính (hoặc thậm chí sử dụng Parallel.ForEach
và sử dụng đếm được tiêu thụ như các nguồn dữ liệu)
void ConsumersInParalell()
{
//This assumes the method signature of DoSomthing is one of the following:
// Action<MagicalObject>
// Action<MagicalObject, ParallelLoopState>
// Action<MagicalObject, ParallelLoopState, long>
Paralell.ForEach(this.Collection.GetConsumingEnumerable(), DoSomthing);
}
Nguồn
2010-06-29 14:45:42
Phiên bản .Net nào bạn đang sử dụng, có một số điều mới cho v4 cho chính xác công cụ này –
.Net 3.5; Nhận xét phải dài ít nhất 15 ký tự. –