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

LCJ*_*LCJ 4 .net c# asp.net web-controls

我有以下使用的"代码 "块上TableHeaderCell,LiteralControl,HyperLinkGridViewRow(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;
                    }
                }

            }
        }




    }
Run Code Online (Sandbox Code Playgroud)

辅助方法

    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);
        }


    }
Run Code Online (Sandbox Code Playgroud)

参考:

  1. 为什么我需要在ASP.NET控件上调用dispose?

Tim*_*ora 6

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

完成使用控件后调用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;
    }
}
Run Code Online (Sandbox Code Playgroud)

何时处理

这并不是说你不应该处置你的资源; 如果一个控制需要处理资源,那么它肯定是免费的.也许控件访问数据库; 我想包一个数据库里面的代码using的控制.

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

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

// could become
cellAssociate.Controls.Add( new LiteralControl { Text = displayName } );
Run Code Online (Sandbox Code Playgroud)

  • 实际上,当页面出现时它将(假设没有错误)被处理掉.但是对于那些拥有非托管资源的少数控件(我确实使用了一个),你真的需要像`var control = new MyControl(); 试试{control.Property = value; page.Controls.Add(对照); } catch {control.Dispose(); 扔; }` (2认同)