4

、、、および( )TableHeaderCellで「<strong>using」ブロックを使用する次のコードがあります。コードはインデントされたとおりに機能しています。以下に示すように、「using」ブロックを使用してコントロールを破棄する際に問題/落とし穴はありますか?はいの場合、落とし穴の詳細を示すmsdnリファレンスを提供できますか?LiteralControlHyperLinkGridViewRowtry..finally

    protected void grdTransactions_RowCreated(object sender, GridViewRowEventArgs e)
    {

        if (e != null)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                GridViewRow newHeaderRow = null;
                try
                {

                    newHeaderRow = new GridViewRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal);

                    using (TableHeaderCell cellFirst = new TableHeaderCell())
                    {
                        cellFirst.ColumnSpan = 1;
                        cellFirst.Text = "FIRST";
                        newHeaderRow.Cells.Add(cellFirst);
                    }


                    using (TableHeaderCell cellAssociate = new TableHeaderCell())
                    {
                        GetTableCell(cellAssociate,"tableColGroupAssociate", 4, "associateHide", "Associate Transaction Info");
                        newHeaderRow.Cells.Add(cellAssociate);
                    }

                    newHeaderRow.Cells.Add(cellAssociate);
                    ((GridView)sender).Controls[0].Controls.AddAt(0, newHeaderRow);

                }
                finally
                {
                    if (newHeaderRow != null)
                    {
                        newHeaderRow.Dispose();
                        newHeaderRow = null;
                    }
                }

            }
        }




    }

ヘルパーメソッド

    private static void GetTableCell(TableHeaderCell cellAssociate, string cssClassName, int colSpan, string hideClassName, string displayName)
    {
        cellAssociate.ColumnSpan = colSpan;
        cellAssociate.CssClass = cssClassName;

        using (LiteralControl ltlText = new LiteralControl())
        {
            ltlText.Text = displayName;
            cellAssociate.Controls.Add(ltlText);
        }

        using (HyperLink lnkHide = new HyperLink())
        {
            lnkHide.Text = SupportToolUIResource.HideLinkText;
            lnkHide.CssClass = hideClassName;
            lnkHide.Target = SupportToolUIResource.HideLinkTarget;
            cellAssociate.Controls.Add(lnkHide);
        }


    }

参照

  1. ASP.NETコントロールでdisposeを呼び出す必要があるのはなぜですか?
4

2 に答える 2

6

コントロールで「完了」した場合でも、ページはレンダリング時にコントロールにアクセスするため、作成中にそれらを破棄してもあまり意味がありません。あなたの例の1つでは、破棄したばかりのコントロールの1つを使用していますが、これも意味がありません。

コントロールの使用が終了したら、Dispose を呼び出します。Dispose メソッドは、Control を使用できない状態のままにします。このメソッドを呼び出した後、コントロールへのすべての参照を解放して、占有していたメモリをガベージ コレクションによって再利用できるようにする必要があります。

コントロールによって発生する Disposed イベントの説明も、意図した使用法を示唆しています。

サーバー コントロールがメモリから解放されたときに発生します。これは、ASP.NET ページが要求されたときのサーバー コントロールのライフサイクルの最終段階です。

ソース: http://msdn.microsoft.com/en-us/library/system.web.ui.control.dispose.aspx
ソース: http://msdn.microsoft.com/en-us/library/system.web .ui.control.disposed.aspx
参照: https://stackoverflow.com/a/3151072/453277

したがって、理論的には:

  1. コントロール ツリーを構築します。
  2. ページのレンダリングが開始されます。
  3. ページは、ツリーに追加されたコントロールを参照します。
  4. コントロールは処分されました。
  5. 潜在的な問題。

IDisposableこれが(from )の実装ですControl。コンテナとイベント関連の値がどのように変更されるかに注意してください。

public virtual void Dispose()
{
    if (this.Site != null)
    {
        IContainer container = (IContainer)this.Site.GetService(typeof(IContainer));
        if (container != null)
        {
            container.Remove(this);
            EventHandler eventHandler = this.Events[Control.EventDisposed] as EventHandler;
            if (eventHandler != null)
            {
                eventHandler(this, EventArgs.Empty);
            }
        }
    }
    if (this._occasionalFields != null)
    {
        this._occasionalFields.Dispose();
    }
    if (this._events != null)
    {
        this._events.Dispose();
        this._events = null;
    }
}

いつ処分するか

これは、リソースを処分してはならないということではありません。コントロールがリソースを破棄する必要がある場合、それは確かに自由です。おそらく、コントロールはデータベースにアクセスします。usingコントロール内のブロックにデータベース コードをラップします。

実際には、このスタイルは、より簡単に表現できるものに対して大きなコード ブロックを作成します。

using (LiteralControl ltlText = new LiteralControl())
{
    ltlText.Text = displayName;
    cellAssociate.Controls.Add(ltlText);
}

// could become
cellAssociate.Controls.Add( new LiteralControl { Text = displayName } );
于 2012-11-19T07:06:29.310 に答える
1

説明とリンクを提供してくれた @Tim Medora に感謝します ASP.NET コントロールで dispose を呼び出す必要があるのはなぜですか? .

興味深い点は次のとおりです。

  1. 私たちがする必要があるControls’ collectionのは、Page が破棄されるときに破棄されるように、新しいコントロールが追加されていることを確認することです。
  2. コントロール オブジェクトは、IDisposable インターフェイスを実装します。各親コントロールは、そのすべての子に対して Dispose を呼び出すことができます
  3. IDisposable を実装し、破棄プロセス中に実際にクリーンアップされる状態データを持つ適切に作成されたオブジェクトは、破棄後にObjectDisposedExceptionパブリック/保護/内部プロパティまたはメソッドのいずれかにアクセスした場合にスローする必要があります。invalid state( Dispose が呼び出された後に仮定します。) 一部の型は、実際にクリーンアップするものがない場合、この規則を無視し、無効な状態について心配する必要はありません。

結論

Web コントロールで "using" ブロックを使用する必要はありません。また、「using」ブロックが Web コントロールで使用されている場合、問題が発生する可能性があります。

于 2012-11-21T17:29:19.200 に答える