クラス名が xxxStream なのに Reader/Writer 系
Stream 系と Reader/Writer 系は、ともに Dispose を呼ぶことで、元となっているリソースとの接続を閉じる。Stream 系と Reader/Writer 系の違いは、Stream 系は使用が終わったら可能な限り早い段階で Dispose を呼び出すことが好ましいことがほとんどであるのに対し、Reader/Writer 系は Dispose を呼び出してはいけないシチュエーションが多々あり、呼び出す必要がなければ呼び出さないでも良い、という点。
この2つの区別はクラス名や派生元クラスをみればわかるような形になっているのだが、例外が System.IO.Compression 下の Stream 達。
ここにある GZipStream 等のクラスは機能的には Reader/Writer 系と同様の、ストリームフィルタ(またはストリームパイプ)として機能するようになっているのだが、「入力データが終端に達したこと」を検出するまで、BaseStream に出力を Flush できないという機能的な問題があり、その検出に Dispose メソッドを利用するという設計になっている。このため、Reader/Writer 系であるにもかかわらず、Dispose の呼び出しが必須になってしまったのだ。
- Reader/Writer が Dispose を呼び出せないシチュエーションにおいて GZipStream などを利用したい場合には、どうすればいいんだろう?
- コンストラクタの3番目の引数に false って付けるだけ。
- どうして Dispose でデータ終端を検出する設計なんだろう?
- データ終端の検出を Dispose にしておけば、using() でデータ書き込み処理を囲んでコードがスッキリ、とかじゃないかな。
- なぜ GZipReader, GZipWriter じゃないの? Reader/Writer だって using() で囲めるよ
- クラス名が Stream で終わってたら using() で囲む等で Dispose する必要がある! という意識をもたせる、ってルールを崩さないためじゃないかしら。
自問自答してみたが、こんなところかしら。
非同期クライアントコールバックのコールバック関数からクライアントコールバックを呼び出すと、コールバック関数が呼ばれ続ける
タイマーなどを利用して回避可能とはいえ、ちょっと困った不具合だ。(既知の不具合だったのですぐに見つかった)
続きを読む