ようこそ。睡眠不足なプログラマのチラ裏です。

スコープ間またはスレッド間をまたいで、オブジェクトの有効期間を管理する

MSDN マガジン - CLR 徹底解剖 オブジェクトの有効期間を管理する

残念ながら、C# には、スコープ間またはスレッド間で使用できる using キーワードと同等の簡単なコンストラクタはありません。このため、Dispose の呼び出しをコンポーネント間でネゴシエートして 1 回だけ適切なタイミングで実行されるようにする必要があるので、コードとルーチンの再利用は困難です。
Dispose を明示的に呼び出さない場合、Dispose はファイナライザによって呼び出され、オブジェクトで Dispose パターンが適切に実装されているかどうかが確認されます。ただし、ファイナライザがいつ呼び出されるかがわからないので、負荷が高い環境ではリソースが不足する可能性があります。また、オブジェクトを作成したスレッドとは異なるスレッドから呼び出されると、ファイナライザは失敗する可能性があります。これは、ファイナライザでアンマネージ リソースまたは COM リソースを解放しようとする場合に問題になることがあります。
この問題の解決策としては、IDisposable を実装するあらゆる型の汎用ラッパー クラスを作成することが考えられます。ラッパー クラスによって IDisposable インターフェイスが返されますが、コンポーネントの呼び出しをデリゲートする前に参照カウンタが内部的に設定されます。図 2 に示すコードでは、AddRef という新しい拡張メソッドを使用して、特定のオブジェクトの内部参照カウンタを含む対応するラッパー オブジェクトを取得します。


という感じで、だいぶ前の記事ですがMSDNマガジンに素敵情報が載っています。
スコープ間またはスレッド間をまたいで使用できる、usingステートメントと同等の機構の作り方について、
手取り足取り詳しく解説をしてくれています。これは目から鱗です。ありがたやありがたや。



で、

.NET リソース管理用の再利用できるスレッド セーフなコードは、
CodePlex の LifeTimeScope.net プロジェクトに含まれています (codeplex.com/lifetimescope を参照)。

とのことなので、早速ダウンロード。

試しにマルチスレッドなコードで動かしてみました。すると、問題なく動作することもありますが、失敗することもあります。
Interlocked.Incrementおよび、Interlocked.Decrementを使っていて、
ぱっと見スレッドセーフっぽいコードに見えるのですが、どこがおかしいんだろうか。
これを適切にスレッドセーフにするにはどうすりゃいいのかな。ReaderWriterLockあたりを使うように変更すればよいのかな。
また、.NETにおいて、あるコードの断片がスレッドセーフであるかどうかを正確に確認する方法とかも知りたい。
マルチスレッドプログラミングの知識は未だに曖昧なところが多いから、繰り返しお勉強しなきゃだなあ。



話はかわりますが、MeCubを使って形態素解析して遊んでます。
「夙川アトム風変換機」を作ってました。既に誰かがやっているだろうなとは思いましたが、
まさか1年以上も前に作ってる人がいたとはー・・・、素敵な人がいたもんだw*1
http://mt.endeworks.jp/d-6/2008/03/post-15.html
http://tech.bayashi.jp/archives/entry/prototype/2008/002080.html


先見的な明がちょいもーしーほー

*1:夙川アトムがテレビに出たのは、笑わず嫌いに出たのが最初だっけか