0

我仍然在我的记忆中泄漏狩猎,我注意到以下几点:异步和CancellationTokens/CancellationTokenSource内存问题

我有很多来自F#的默认未来System.Threading.CancellationCallbackInfo对象的实时实例-CancellationTokenSource(异步工作流)。

如果您自己声明一个Source并在MailboxProcessor中使用它来跨越子节点或任务,则问题会变得更糟。

好像因为CancellationTokenSource是抱着这样的引用GC无法收集那些跨越任务/工作流程: enter image description here

其中大多数CancellationCallbackInfo对象的获取到第二代 - 令人难以置信的,因为我只使用内部的本地引用邮箱处理器 - “循环”工作流程...

这是一个已知问题,是否有解决方案/解决方法?

现在我采空用取消支持和线程ManualResetEvents通过代码这个......不是很好,在所有:(

+0

您能发布一个演示行为的(最小)示例吗?我很难分析问题,但却无法自己运行... – 2012-03-15 11:38:31

+0

我不在办公室的ATM机上,但我会尽快在代码中插入一些东西 - 但核心并不那么困难:这部分直接来自一个MailboxProcessor,我用它作为“排队”IObservable实现的主力(将值排入MailboxProcessors-inbox和Processor“OnNext”所有注册的观察者) - 所涉及的任务不在其中的部分一个邮箱处理器,但是在一个尾递归异步的“Check”-Loop构造中,它跨越了尝试异步ping一个远程主机的任务 – Carsten 2012-03-15 15:19:13

回答

3

如果使用StartChild,有泄漏存在(见this)这将被固定在下一版本中,您可以通过使用StartAsTask解决它。

它是用自己的CancellationTokenSource创建一个令牌,并明确传递令牌F#异步操作一个很好的做法,这样就可以Dispose CTS按照您自己的条款。

(如果您看到不涉及StartChild的不同泄漏,我们会喜欢一个小的repro,所以我们可以修复它!)

+0

明天我会检查接下来的事情。我认为开始使用任务只会创建更多的任务 - 链接到相同TokenSource的内存中的对象(以及那些任务对象实际上是昂贵的内存方式,所以我采用了这种方式) - 我认为我产生了子任务与Async.Start现在,因为我真的不需要结果(第一个版本刚刚添加了一个异常处理程序与ContinueWith - 它现在通过包装工作流完成) – Carsten 2012-03-15 20:17:02

+0

我确实有一个StartChild实例在那里 - 删除这个和找不到一个简单的例子锁定内存中的东西...所以我想我可以标记你的答案 – Carsten 2012-03-16 07:51:44