简体   繁体   English

在ActionBlock中收集结果时阻止收集

[英]Blocking collection when collect results inside ActionBlock

I think in the test method the "results" collection variable has to be of type BlockingCollection<int> instead of List<int> . 我认为在测试方法中,“results”集合变量必须是BlockingCollection<int>而不是List<int> Prove it to me if I am wrong. 如果我错了,请向我证明。 I have taken this example from https://blog.stephencleary.com/2012/11/async-producerconsumer-queue-using.html 我从https://blog.stephencleary.com/2012/11/async-producerconsumer-queue-using.html中采用了这个例子

private static async Task Produce(BufferBlock<int> queue, IEnumerable<int> values)
{
    foreach (var value in values)
    {
        await queue.SendAsync(value);
    }
}

public async Task ProduceAll(BufferBlock<int> queue)
{
    var producer1 = Produce(queue, Enumerable.Range(0, 10));
    var producer2 = Produce(queue, Enumerable.Range(10, 10));
    var producer3 = Produce(queue, Enumerable.Range(20, 10));
    await Task.WhenAll(producer1, producer2, producer3);
    queue.Complete();
}

[TestMethod]
public async Task ConsumerReceivesCorrectValues()
{
    var results = new List<int>();

    // Define the mesh.
    var queue = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 5, });

    //var consumerOptions = new ExecutionDataflowBlockOptions { BoundedCapacity = 1, };

    var consumer = new ActionBlock<int>(x => results.Add(x), consumerOptions);
    queue.LinkTo(consumer, new DataflowLinkOptions { PropagateCompletion = true, });

    // Start the producers.
    var producers = ProduceAll(queue);

    // Wait for everything to complete.
    await Task.WhenAll(producers, consumer.Completion);

    // Ensure the consumer got what the producer sent.
    Assert.IsTrue(results.OrderBy(x => x).SequenceEqual(Enumerable.Range(0, 30)));
}

Since ActionBlock<T> restricts its delegate to one-execution-at-a-time by default ( MaxDegreeOfParallelism of 1 ), it is not necessary to use BlockingCollection<T> instead of List<T> . 由于ActionBlock<T>默认情况下将其委托限制为一次执行一次( MaxDegreeOfParallelism1 ),因此不必使用BlockingCollection<T>而不是List<T>

The test in your code passes just fine for me, as expected. 正如预期的那样,代码中的测试对我来说很合适。

If ActionBlock<T> were passed an option with a higher MaxDegreeOfParallelism , then you would need to protect the List<T> or replace it with a BlockingCollection<T> . 如果ActionBlock<T>传递了一个具有更高MaxDegreeOfParallelism的选项,那么您需要保护List<T>或用BlockingCollection<T>替换它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM