using (BlockingCollection<int> bc = new BlockingCollection<int>())
{
Task.Factory.StartNew(() =>
{
for (int i = 0; i < 1000; i++)
{
bc.Add(i);
Thread.Sleep(50);
}
// Need to do this to keep foreach below from hanging
bc.CompleteAdding();
});
// Now consume the blocking collection with foreach.
// Use bc.GetConsumingEnumerable() instead of just bc because the
// former will block waiting for completion and the latter will
// simply take a snapshot of the current state of the underlying collection.
foreach (var item in bc.GetConsumingEnumerable())
{
Console.WriteLine(item);
}
}public IEnumerable<T> GetConsumingEnumerable(CancellationToken cancellationToken)
{
CancellationTokenSource linkedTokenSource = null;
try
{
linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _consumersCancellationTokenSource.Token);
while (!IsCompleted)
{
T item;
if (TryTakeWithNoTimeValidation(out item, Timeout.Infinite, cancellationToken, linkedTokenSource))
{
yield return item;
}
}
}
finally
{
if (linkedTokenSource != null)
{
linkedTokenSource.Dispose();
}
}
}
public bool IsCompleted
{
get
{
CheckDisposed();
return (IsAddingCompleted && (_occupiedNodes.CurrentCount == 0));
}
}原文:http://blog.csdn.net/lan_liang/article/details/50461432