none
System.ComponentModel.BackgroundWorker や DataSetのDispose RRS feed

  • 質問

  • こんばんは。もんたといいます。

    いま、Windows Forms アプリケーションでBackgroundWorkerクラスを使って実装しようとしています。

    デザインモードでFormにBackgroundWorkerを貼り付けて、実装しています。

    そこで、ふと気になったのですが、BackgroundWorkerのインスタンスって、いつDisposeされるのだろう?と思いました。BackgroundWorkerはControlじゃないので、FormのClose時に一緒にDisposeされません。

    同様の理由で、DataSetもDisposeされないのでは?と思っています。

    そこで質問ですが、このように、System.ComponentModel.ComponentクラスのインスタンスのDisposeって、どのように実装すればよいか、教えていただけないでしょうか?

    よろしくおねがいします。

    2006年4月7日 17:51

すべての返信

  • >同様の理由で、DataSetもDisposeされないのでは?と思っています。

    BackgroundWorkerについてはよくわからないのですが、DataSetではDisposeに何も実装されていません。つまり、Disposeを実行しても何の変化もありません。

    >そこで質問ですが、このように、System.ComponentModel.ComponentクラスのインスタンスのDisposeって、どのように実装すればよいか、教えていただけないでしょうか?

    一般的にはアンマネージリソースの開放、また、クラスのインスタンスメンバーで巨大なメモリーを消費するような場合で、クラスのインスタンスは存続し続けながらそれを開放したい場合などは、用意した方がいいでしょう。いや、すべきでしょう。

    2006年4月10日 11:09
    モデレータ
  • デザイナで貼り付けたなら、FormのDispose時にDisposeされると思いますが…

     

    2006年4月11日 15:37
  • デザイナで貼り付けたなら、FormのDispose時にDisposeされると思いますが…

     


    「思います」ではなく確認してから発言しましょう。

    デザイナーでFormにBackgrondWorkerを貼り付けてもFormのcomponentsに追加されません。

    2010年12月7日 2:40
  • BackgroundWorker や DataSet は Dispose() は誰も呼ばないのが通例です。

    Visual Studio のフォームデザイナは、「Component の派生クラス かつ Control の派生クラスではない かつ Dispose メソッドを実装しているもの」をフォーム自身の components コレクションに登録して管理します。BackgroundWorker や DataSet では、Dispose メソッドを実装していないため「Dispose を行う必要がない」と判断されて、フォームの Dispose() からの連携対象外として扱われているわけです。

    ※ Component クラスを派生しているのは、Visual Stuido のようなデザイナがツールボックスに登録するための親クラスとして要求するためです。

    2010年12月7日 3:12
  • 随分昔のスレッドですね。

    K.Takaoka さん
    > BackgroundWorker や DataSet は Dispose() は誰も呼ばないのが通例です。

    デザイナで使用するかどうかに関係なく、本当は不要になった時点で呼ばれるべき(呼ぶべき)と私は思いますけどね。。。

    > BackgroundWorker や DataSet では、Dispose メソッドを実装していないため「Dispose を行う必要がない」と判断されて、フォームの Dispose() からの連携対象外として扱われているわけです。

    両方とも Dispose メソッドは実装していますので、条件としては、インターフェイスを「明示的に」実装しているかどうかでしょうか?
    Component がすでにパターンにのっとって Dispose を実装していますので、おそらく Component の派生クラスが明示的に Dispose を実装することは実質ありえないのかなと思いました。
    すると、本来は明示的かどうかに関係なく、実装していれば components に登録されるべきじゃないかと思いました。
    なので、なんとなく設計ミスのような気がしました。

    追記:
    試してみればわかることでしたが、K.Takaoka さんが言いきられていたので、一部間違ってるだけで大筋はあってると信じてしまいました。
    と書くと、K.Takaoka さんに対する嫌味になっちゃいますが、自分のために書かせてもらいます。(^^; 性格が悪くてすみません。。

    • 編集済み TH01 2010年12月7日 7:34 追記
    2010年12月7日 6:19
  • components に登録するかどうかは、そのコンポーネントクラスが IContainer を引数に取るコンストラクタを持っているかどうかです。Dispose とは直接的には関係ありません。

    2010年12月7日 6:51
  • そういうことですか、納得しました。
    以下のコードで試すと、確かにそうなりました。
    自動的に Add されるんじゃなくて、デザイナのコードが components を渡してくれるから、そこに自分で Add するんですね。

    public class MyComponent : Component
    {
        public MyComponent() : base() { }
        public MyComponent(IContainer container) : this()
        {
            container.Add(this);
        }

        protected override void Dispose(bool disposing)
        {
            // デザイナの components.Dispose(); 時に、
            // ここがちゃんと呼び出されました。
            base.Dispose(disposing);
        }
    }

    2010年12月7日 7:27
  • VS2008 を使ってみたところ、書かれている通りになっていますね。すいません。
    ※ これ古い記事なんですねえ、私はフォーラムを更新履歴でしかみていないので…

    (昔は、メソッドを override すると挙動がかわったのですが、記憶違いかなぁ…と思って検索すると、同じことを書いてる記事が出てくるので今は違うんですかね…)

     

    2010年12月7日 9:11