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