问题描述
我正在尝试使用操作块来执行一些任务。我的问题是当 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