在Webcontrols上使用“使用”块有什么问题?

时间:2012-11-19 06:55:44

标签: c# asp.net .net web-controls

我在TableHeaderCellLiteralControlHyperLinkGridViewRow try..finally使用了“使用”块代码)。代码是缩进的。使用“using”块处理控件时是否有任何问题/陷阱如下所示?如果是的话,你能提供任何显示陷阱细节的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. Why would I need to call dispose on ASP.NET Controls?

2 个答案:

答案 0 :(得分:6)

即使您对控件“完成”,页面也会在渲染时访问控件,因此在构造期间处理它们没有多大意义。在您的一个示例中,您正在使用刚刚处理的控件之一,这也没有意义。

  

使用完控件后调用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. 潜在问题。
  6. 以下是IDisposable(来自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;
        }
    }
    

    何时处理

    这并不是说你不应该处置你的资源;如果一个控制需要处理资源,那么它肯定是免费的。也许控件访问数据库;我将数据库代码包装在<{1}}块里面控件中。

    实际上,这种风格为可以更简单地表达的东西创建了一大块代码。

    using

答案 1 :(得分:1)

感谢@Tim Medora的解释和链接Why would I need to call dispose on ASP.NET Controls?

有些兴趣点是:

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

    无需在webcontrols上使用“使用”块。此外,如果在webcontrol上使用“using”块,则可能会导致问题。