AppDomain の強制アンロード

クロニカ学習帳を持った死神さんの話.

いろいろと試してみるとAppDomain経由で起動したアプリケーションがバックグラウンドでスレッドを生成するとUnloadに失敗する事が多いことが判明した。(100%じゃない)AppDomainのUnloadには時間がかかる、といろいろな所で書いているしスレッドが消えるまで放っておけば良いとも言えるけど開発するアプリケーションにはインスタンス数の制限があり、消えかけのAppDomainが残っていると間違いなくインスタンス数のカウントを間違える。

何か良い方法が無いかなと暫く考えているんだけど今のところ打開策無し....

C# 2.0 ということで CLR 2.0 環境での話ですよね.例えばスレッドを (gracefully) abort させようとするときに finnaly ブロックで無限ループが起きたりすると,タイムアウトが設定されていないので永遠に待ち続けるということもあり得るかもしれません*1

In general, hosts that require a process to live for a long time are likely to want to specify timeout values for at least OPR_ThreadAbort, OPR_AppDomainUnload, and OPR_FinalizerRun because there are no default timeout values for these operations. That is, unless a host specifies a timeout, attempts to abort a thread or unload an application domain could take an infinite amount of time. The CLR does have a default timeout for OPR_ProcessExit, however. If a process doesn't gracefully exit in approximately 40 seconds, the process is forcefully terminated.

もっともベータ版を元に書かれた本なので,その後のバージョンや RTM 版でどうなるかは分かりませんけど.
とりあえずオフィシャルな解決方式のひとつは,CLR Hosting API 経由でスレッドの abort と AppDomain の unload にタイムアウトを設定することでしょうか.

hr = pCLRPolicyManager->SetTimeoutAndAction (OPR_ThredAbort, 10*1000, eRudeAbortThread);
hr = pCLRPolicyManager->SetTimeoutAndAction (OPR_AppDomainUnload, 20*1000, eRudeUnloadAppDomain);

ちょうど beta 2 待ちで手元にテスト環境がないのがつらいところですが.

*1:一方プロセスの強制終了については 40 秒のタイムアウトが存在するので確実に殺されます.きっと死因は心臓麻痺でしょう.