4

MailboxProcessor を使用する F# プロジェクトの TFS テストの実行を修正するのに苦労しています。問題は、TFS テスト ランナーから受け取る次の警告です。

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 がdeadと表示されるはずです。しかし、それは生きています。何らかのメモリリークを示していると思います。問題は、私が何を間違っているかです。2 つ目の質問は、GC の問題が TFS テスト ランナーの問題に関連しているかどうかです。

4

1 に答える 1