gpt4 book ai didi

c# - asp.net控件什么时候释放

转载 作者:行者123 更新时间:2023-11-30 21:11:58 25 4
gpt4 key购买 nike

我正在寻找 asp.net 网站中的内存泄漏。我发现的一个是,当不再需要控件时,代码不会释放事件处理程序。我使用 MSDN 上显示的处理模式来清理它们,并将删除事件处理程序的调用放在 if (disposing) block 中,因为它们是托管资源,但除非我通过并向每个页面添加析构函数并让它们全部手动处理控件在终结器清理困惑之前不会触发任何内容。那样做会很脆弱,并且使将来重新引入泄漏变得相对容易;我是否最好忽略关于在终结器运行的代码中不接触非托管对象的约定?

// Design pattern for a base class.
public class Base: IDisposable
{
//Implement IDisposable.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
myControl.SomeEvent -= SomeEventHandler;
// Free other state (managed objects).
}
// Free your own state (unmanaged objects).
// Set large fields to null.
}

// Use C# destructor syntax for finalization code.
~Base()
{
// Simply call Dispose(false).
Dispose (false);
}
}

最佳答案

When are asp.net controls disposed

从不,如果有任何实时引用。

如果您有任何 Disposable 对象,调用 Dispose 方法是最佳做法。如果您只是允许它们超出范围,它们将在第一个垃圾回收周期中被添加到终结队列中。并会在终结后的第二个垃圾回收周期释放内存。如果您可以调用 Dispose 方法和 SuppressFinalization,则终结是不必要的开销。

另一件事在您的代码示例中。拥有 Finalize 方法,但没有任何非托管代码。如果您查看 Finalize->Dispose(false) 的执行路径,您会注意到它什么都不做。因为所有的托管对象只有在disposing时才会被处理。因此,如果您没有任何非托管对象,则没有必要添加 Finalize 方法。

只有当该对象没有任何事件引用(在第一个 GC 循环中)时,该对象才会被添加到终结队列并调用 Finalize 方法。因此,您有责任取消注册必要的事件。否则,只要存在对该对象的引用,Finalize 就永远不会执行。

这里有一个关于取消注册事件处理程序的很好的引用。

Is it necessary to explicitly remove event handlers in C#

关于c# - asp.net控件什么时候释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7773255/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com