如果我没有完成ActionBlock会不会有问题

问题描述

我正在尝试使用操作块来执行一些任务。我的问题是当 CreateActionBlock() 方法完成时,ActionBlock 仍在处理数据。由于该方法已返回并且我无法调用 actionBlock.Complete()。如果我运行这个 CreateActionBlock() 千次会导致任何问题吗?内存中会永远有上千个 actionBlocks 还是会在处理 5 个输入后被 GC 处理?

private static async Task Dequeue(string content)
{
    Console.WriteLine("The string is " + content);
    await Task.Delay(10000);
}

public static void CreateActionBlock()
{
    var actionBlock = new ActionBlock<string>(
        (e) => Dequeue(e),new ExecutionDataflowBlockOptions()
        {
            BoundedCapacity = 5,MaxDegreeOfParallelism = 1
        });

    for (int i = 0; i < 5; i++)
    {
        actionBlock.Post(i.ToString());
    }
}

解决方法

只要输入队列被清空,并且当前空闲,数据流块就有资格进行垃圾回收。下面是演示此行为的示例:

var weakReference = InnerMethod();
for (int i = 1; i <= 10; i++)
{
    Thread.Sleep(100);
    GC.Collect();
    Console.WriteLine($"IsAlive: {weakReference.IsAlive}");
}

WeakReference InnerMethod()
{
    var block = new ActionBlock<int>(n =>
    {
        Thread.Sleep(200);
        Console.WriteLine($"Processed: {n}");
    });
    block.Post(1); block.Post(2); block.Post(3);
    return new WeakReference(block);
}

输出:

IsAlive: True
Processed: 1
IsAlive: True
IsAlive: True
Processed: 2
IsAlive: True
IsAlive: True
Processed: 3
IsAlive: False
IsAlive: False
IsAlive: False
IsAlive: False
IsAlive: False

(Try it on Fiddle)