Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么&x2019;使用“;使用”;阻止网络控制?_C#_Asp.net_.net_Web Controls - Fatal编程技术网

C# 什么&x2019;使用“;使用”;阻止网络控制?

C# 什么&x2019;使用“;使用”;阻止网络控制?,c#,asp.net,.net,web-controls,C#,Asp.net,.net,Web Controls,我有以下代码在TableHeaderCell、LiteralControl、HyperLink和GridViewRow(try..finally)上使用“using”块。代码以缩进方式工作。在使用如下所示的“使用”块处理控件时是否存在任何问题/陷阱?如果是,您能否提供任何msdn参考,以显示陷阱的详细信息 protected void grdTransactions_RowCreated(object sender, GridViewRowEventArgs e) {

我有以下代码在
TableHeaderCell
LiteralControl
HyperLink
GridViewRow
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);
        }


    }
参考

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

    使用完控件后调用Dispose。处置 方法使控件处于不可用状态。打了这个电话之后 方法,则必须释放对该控件的所有引用,以便 它可以通过垃圾收集回收

    控件引发的已处置事件的描述还提示了预期用途:

    从内存中释放服务器控件时发生,这是 服务器控件生命周期的最后阶段,此时ASP.NET页处于 请求

    来源:
    来源:
    另见:

    因此,理论上:

  • 建立控制树
  • 页面开始呈现
  • 页面查看添加到树中的控件
  • 控制措施已经解除
  • 潜在问题
  • 以下是
    IDisposable
    (来自
    控件
    )的实现。注意它是如何改变容器和事件相关值的

    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 (LiteralControl ltlText = new LiteralControl())
    {
        ltlText.Text = displayName;
        cellAssociate.Controls.Add(ltlText);
    }
    
    // could become
    cellAssociate.Controls.Add( new LiteralControl { Text = displayName } );
    

    感谢@Tim Medora的解释和链接

    有几点值得注意:

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


    无需在网络控制上使用“使用”块。此外,如果在WebControl上使用“using”(使用)块,则可能会导致问题。

    是的,但如果发生异常,
    LiteralControl
    将不被处理,这就是
    使用
    很容易防止的。
    LiteralControl
    不会有任何非托管资源,但其他控件可以。控件可以,但大多数控件没有。但实际上,页面生命周期的最后一步是呈现。将控件添加到控件树表明它将被呈现,因此不应在早期阶段进行处理。事实上,当页面被呈现时,它将被处理(假设没有错误)。但是对于那些有非托管资源的少数控件(我确实使用了一个),您确实需要类似
    var control=new MyControl();试试{control.Property=value;page.Controls.Add(control);}catch{control.Dispose();throw;}
    好的,我同意你的观点(尽管我反对控件的这种设计)。但是您的示例使用了一个
    catch
    ;使用
    块相当于
    try/finally
    块,因此即使成功,整个过程也将始终得到处理。我想我的观点是,超链接、文本和表单元格不需要显式处置,它实际上可能会导致意外行为。请看我引用的引用,其中指出“Dispose方法使控件处于不可用状态。”。另请参阅Control.Dispose()的源代码(这是大多数控件子类使用的基本实现)。