我在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);
}
}
参考:
答案 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
所以理论上:
以下是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?。
有些兴趣点是:
Controls’ collection
中添加新控件,以便在处理页面时将其处理。 ObjectDisposedException
或处置后会访问方法。 (在调用Dispose之后假设invalid state
。)如果某些类型实际上没有任何要清理的东西,则忽略这个规则,并且不必担心无效状态。 <强>结论强>
无需在webcontrols上使用“使用”块。此外,如果在webcontrol上使用“using”块,则可能会导致问题。