【发布时间】:2016-12-12 19:09:29
【问题描述】:
我通过以下方式设置流程:
_publisherQueue = CreateBuffer();
var batchingBlock = CreateBatchBlock(options.BatchSize);
var debounceBlock = CreateDebounceBlock(options.DebounceInterval, batchingBlock.TriggerBatch);
var publishBlock = CreatePublishBlock();
var groupByTopicBlock = CreateGroupByTopicBlock(publishBlock);
_publisherQueue.LinkTo(debounceBlock, new DataflowLinkOptions { PropagateCompletion = true});
debounceBlock.LinkTo(batchingBlock, new DataflowLinkOptions { PropagateCompletion = true });
batchingBlock.LinkTo(groupByTopicBlock, new DataflowLinkOptions { PropagateCompletion = true });
地点:
-
CreateDebounceBlock返回一个变换块(带有定时器来触发batchblock) -
CreateGroupByTopicBlock返回一个ActionBlock,其Action触发CreatePublishBlock返回的动作块
我无法处理这些链接,因为此流程应该在程序的整个生命周期内都存在(在这种情况下,它是一个 Windows 服务)。
我注意到每次调用_publisherQueue(即BufferBlock)时都会使用一些内存,这是正常的,但是在进程完成后分配的内存不会被释放。
这令人担忧,因为这是一个长时间运行的进程,会以随机间隔接受输入。
这是我第一次尝试使用 TPL,所以很可能我没有进行适当的处理。但是我不确定我需要处理什么,因为我需要这些结构在程序的整个生命周期内保持活跃。
【问题讨论】:
-
您所说的“进程已完成”是什么意思,您如何测量内存仍然分配?
-
@PeterRitchie 使用 VS 中的诊断工具。 “流程已完成”意味着我在缓冲区中添加了一些内容,它通过了整个流程并发布了。在这一点上,我希望为执行流程分配的内存被释放
-
为什么?如果你没有用
Complete()告诉流程它已经完成,那么就没有理由发布任何东西。您可能会在下一纳秒内发布另一条消息。流需要处理大量消息,尤其是在服务中使用时。 -
您在诊断工具窗口中看到的内存很可能可用于垃圾收集。它不会被收集,除非 GC 运行(显示为橙色标记)。或者你可能有内存泄漏。在内存选项卡中拍摄两个快照,以查看哪些新对象幸存下来以及它们被分配到哪里
-
@PanagiotisKanavos 感谢您的 cmets。实际上,Complete 方法是我最好奇的。我不确定何时调用 Complete。我同意我可以在下一纳秒内发布另一条消息,因此如果我正确理解 Complete 方法的作用,我只能在程序关闭时调用 Complete 方法。
标签: c# asynchronous parallel-processing task-parallel-library tpl-dataflow