我被困在修復使用MailboxProcessor的F#項目中運行的TFS測試。問題是我收到來自TFS測試運行器的以下警告:MailboxProcessor.Dispose不會使對象GC可收集
System.AppDomainUnloadedException:試圖訪問卸載的AppDomain。如果測試開始一個線程但沒有停止,就會發生這種情況。確保在完成之前停止由測試啓動的所有線程。
我猜這個問題是由MailboxProcessor造成的。下面的代碼演示問題(我從FSI運行它):
open System.Threading
open System
type TestDisposable() =
let cts = new CancellationTokenSource()
let processMessage (inbox:MailboxProcessor<int>) =
let rec loop n =
async {
let! msg = inbox.Receive()
return! loop (n+msg)
}
loop 0
let agent = MailboxProcessor<int>.Start (processMessage, cts.Token)
interface IDisposable with
member this.Dispose() =
(agent :> IDisposable).Dispose()
cts.Cancel()
cts.Dispose()
printfn "TestDisposable.Dispose called"
do
let weakTarget =
use target = new TestDisposable()
new WeakReference (target)
GC.Collect()
GC.WaitForPendingFinalizers()
GC.WaitForFullGCComplete() |> ignore
GC.Collect()
printfn "WeakTarget is alive: %b" weakTarget.IsAlive
我希望輸出線說weakTarget是死。但其活着。 我認爲這表明一些內存泄漏。問題是我做錯了什麼? 第二個問題是GC問題是否與TFS測試運行器問題有關。
我會說最初的錯誤可能是由於郵箱處理器可能會在郵箱處理器處理完之後啓動多餘的線程而造成的。這是一個完全自然的性能優化。 –
同意。而問題是「我怎樣才能殺死郵箱處理器」? – Sly
我運行了一個簡單的測試,通過運行無限循環創建新的'TestDisposable'來實際發生垃圾收集。經過500k次迭代後,我看到內存使用量沒有增加。我建議你的'GC'功能沒有做你的想法。 –