C#2.0時代のゲームプログラミング(4)

次に、リソースの解放をいつ行なうかについて考えていこう。


プログラミングMicrosoft .NET Framework (マイクロソフト公式解説書)


GCの挙動が嫌らしいのは、私が思うにGCが実行されているスレッドがGC専用のスレッドであることだ。つまり、非同期で、しかもそのclassをnewしたスレッドとは異なるスレッドからそのclassのfinalizerが呼び出される。これが非常にまずいケースが多いのだ。このため、スレッドに関連付けられているunmanagedなリソースは、ことごとく解放に失敗する。


この問題はしばしば議論される(id:akiramei:20060125:p2)のだが、私は言語的にどうこう出来る問題ではないと考えている。だから、我々は、Disposeを確実に呼び出す仕組みを“自分で”作らなくてはならない。



CLR via C# (Developer Reference)


どうやるのか?幸いにしてtask systemという偉大な発明が我々の手中にある。ある規模の処理をすべてtask化し、taskの終了のときに、task systemがtaskのDisposeを呼び出すことを保証すれば良い。これにより、taskの終了と同時にDisposeが呼び出されることが保証される。あとはDisposeで、自分のクラス内で生成したリソースの解放を保証するだけで良い。(YanesdkのTaskSystemがそういう実装になっているのは、このためだ。)


あるクラスがIDispose interfaceを持つかどうかは、asでcastしてみればわかる。こんなにasを気軽に多用して良いのかという気もしなくはないが、このasに実行時に要するコストは、(まともなコンパイラ実装ならば)無視できると考えて良いと思う。PQ encodingされていれば、このasに必要なコストは微々たるものだからだ。(誰かVS2005やmonoの実装がどうなっているか調べてレポートして欲しい)


(つづく)