4

我有以下代码在 、 和 ( ) 上使用“<strong TableHeaderCell> LiteralControlusing HyperLinkGridViewRowtry..finally。代码按缩进方式工作。如下所示使用“使用”块处理控件是否有任何问题/陷阱?如果是,您能否提供任何显示陷阱详细信息的 msdn 参考?

    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

即使您已经“完成”了控件,页面在呈现时也会访问该控件,因此在构造过程中处理它们并没有多大意义。在您的一个示例中,您正在使用您刚刚处置的控件之一,这也没有任何意义。

使用完控件后调用 Dispose。Dispose 方法使控件处于不可用状态。调用此方法后,您必须释放对控件的所有引用,以便它所占用的内存可以通过垃圾回收回收。

控件引发的 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 的解释和链接Why would I need to call dispose on ASP.NET Controls? .

一些兴趣点是:

  1. 我们需要做的是确保添加的新控件在页面中,Controls’ collection以便在释放页面时将其释放。
  2. 控件对象实现 IDisposable 接口。每个父控件都可以对其所有子控件调用 Dispose
  3. 任何实现 IDisposable 并具有在处置过程中实际清理的状态数据的正确编写的对象,ObjectDisposedException如果在处置后访问其任何公共/受保护/内部属性方法,则应抛出一个。(假设invalid state在调用 Dispose 之后。)如果某些类型实际上没有任何要清理的内容,它们将忽略此规则,并且不必担心无效状态。

结论

无需在 web 控件上使用“使用”块。此外,如果在 web 控件上使用“使用”块,可能会导致问题。

于 2012-11-21T17:29:19.200 回答