我最近与同事讨论了Dispose实施的价值和类型IDisposable.
我认为即使没有非托管资源可以清理IDisposable,也应该尽快清理类型.
我的同事有不同的想法; 执行IDisposable,如果你没有任何非托管资源为你的类型,最终会被垃圾收集是没有必要的.
我的论点是,如果你有一个想要尽快关闭的ADO.NET连接,那么实现IDisposable并且using new MyThingWithAConnection()有意义.我的同事回答说,在封面下,ADO.NET连接是一种非托管资源.我对他回复的答复是,最终所有东西都是一种非托管资源.
我知道推荐的一次性模式,如果Dispose被调用,你可以免费使用托管和非托管资源,但是如果通过终结器/析构函数调用,则只有免费的非托管资源(前面有关于如何提醒消费者不正确使用您的IDisposable类型的博客)
所以,我的问题是,如果你有一个不包含非托管资源的类型,是否值得实现IDisposable?
我认为如果您的程序没有,GC会最终调用Dispose,但是您应该在程序中调用Dispose()以使清除确定性.
但是,从我的小测试程序来看,我根本没有看到Dispose被调用....
public class Test : IDisposable
{
static void Main(string[] args)
{
Test s = new Test();
s = null;
GC.Collect();
Console.ReadLine();
}
public Test()
{
Console.WriteLine("Constructor");
}
public void Dispose()
{
Console.WriteLine("Dispose");
}
}
Run Code Online (Sandbox Code Playgroud)
//输出只是"构造函数",我没有像我期望的那样得到"Dispose".这是怎么回事?
编辑:是的,我知道我应该调用Dispose() - 我在使用一次性物体时遵循标准模式.我的问题出现了,因为我试图追踪某些elses代码的漏洞,这是托管C++(另一层复杂性,这将是另一个线程的好主题).
如果我不调用此代码段中Dispose的pen对象会发生什么?
private void panel_Paint(object sender, PaintEventArgs e)
{
var pen = Pen(Color.White, 1);
//Do some drawing
}
Run Code Online (Sandbox Code Playgroud) 我需要一些关于该Dispose方法实现的建议.
在我们的应用程序中,用户设计自己的UI.我有一个预览窗口,显示UI的外观.此UI中绘制的所有对象最终都来自公共基类ScreenObject.我的预览管理器包含对ScreenGrid的单个对象引用,ScreenGrid是整个预览区域的网格对象.
问题#1
我的一些派生屏幕类保留了非托管资源,例如数据库连接,位图图像和WebBrowser控件.这些类需要处理这些对象.我在基类中创建了一个虚Dispose方法,ScreenObject然后Dispose在每个派生类中实现了一个覆盖非托管资源的覆盖方法.但是,现在我刚刚创建了一个名为的方法Dispose,我没有实现IDisposable.我应该实施IDisposable吗?如果是这样,我该如何实现它?
将虚Dispose方法放在没有非托管资源的基类中是否错误,以便您可以利用多态?
问题2
在阅读有关Dispose方法和IDisposable接口的过程中,Microsoft声明处置对象应该只调用Dispose其父对象的方法.父母将为其父母调用它,依此类推.对我而言,这似乎是倒退.我可能想要处理一个孩子但保留其父母.
我认为它应该是另一种方式,处置的对象应该处理它的孩子.然后孩子们应该处理他们的孩子等等.
我错在这里还是我错过了什么?
我正在Windows Server 2003 x64(2x Xeon 4核心触发器)上运行一个大型.net 4.0 x86应用程序,并且遇到了我的应用程序〜每天2-3次冻结30秒,然后恢复正常运行的问题.该应用程序每周只重启一次,消耗400-800 MB的内存,所以我假设这些冻结是垃圾收集.我只看到日志中的冻结,而不是现场,或者我会检查任务管理器确认.
我试图找出哪个.Net 4 GC正在运行,以及如何将GC切换到新的并发背景gc(如果不是),或者如何确认这些实际上是GC(Procmon不显示.Net) Win2k3服务器中的仪器).
析构函数应该只释放对象所持有的非托管资源,并且不应该引用其他对象.如果您只有托管引用,则不需要(也不应该)实现析构函数.您希望这仅用于处理非托管资源.因为拥有析构函数需要一些成本,所以你应该只在消耗有价值的非托管资源的方法上实现它.
文章没有深入讨论这个问题,但在C#中使用析构函数会涉及哪些成本?
注意:我知道GC以及在可靠的时候没有调用析构函数的事实,除此之外,还有什么吗?
我新客户所在的代码审查清单如下 -
实现Dispose和Finalize的类应该在Dispose实现中调用GC.SupressFinalize
为什么?
它是否应该读取为实现IDisposable接口的类应该在Dispose实现中调用GC.SupressFinalize?
或者我错过了一些愚蠢的东西?
.net garbage-collection idisposable finalizer suppressfinalize
在我的应用程序中,每个租户都有自己的StructureMap容器.
在运行时,可以关闭或重新启动租户实例.我应该做什么整理(比如调用IContainer.Dispose)或者我应该让Garbage Collection做它的工作吗?
我们确实有许多实现IDisposable的单例实例.理想情况下,我们应该在处理容器之前调用Dispose.我知道这是在嵌套容器上自动完成的,但不确定标准容器?
谢谢,
本
我使用以下代码根据EXIF数据修复图像的方向
Image FixImageOrientation(Image srce)
{
const int ExifOrientationId = 0x112;
// Read orientation tag
if (!srce.PropertyIdList.Contains(ExifOrientationId)) return srce;
var prop = srce.GetPropertyItem(ExifOrientationId);
var orient = BitConverter.ToInt16(prop.Value, 0);
// Force value to 1
prop.Value = BitConverter.GetBytes((short)1);
srce.SetPropertyItem(prop);
// MessageBox.Show(orient.ToString());
// Rotate/flip image according to <orient>
switch (orient)
{
case 1:
srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
return srce;
case 2:
srce.RotateFlip(RotateFlipType.RotateNoneFlipX);
return srce;
case 3:
srce.RotateFlip(RotateFlipType.Rotate180FlipNone);
return srce;
case 4:
srce.RotateFlip(RotateFlipType.Rotate180FlipX);
return srce;
case 5:
srce.RotateFlip(RotateFlipType.Rotate90FlipX);
return srce;
case 6:
srce.RotateFlip(RotateFlipType.Rotate90FlipNone);
return srce;
case 7:
srce.RotateFlip(RotateFlipType.Rotate270FlipX); …Run Code Online (Sandbox Code Playgroud) c# ×6
.net ×4
dispose ×3
finalizer ×3
idisposable ×3
bitmap ×1
destructor ×1
finalization ×1
gdi+ ×1
memory ×1
structuremap ×1
winforms ×1