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()的源代码(这是大多数控件子类使用的基本实现)。