函数内的Dispose方法是否重要?

5

最近我一直在使用一次性对象,我想知道在函数内部处理对象时是否有必要释放一个对象?比如在这两个函数之间,.Dispose() 在函数内部真的很重要吗?因为在函数完成后,函数中的所有对象都会消失。

void FOO()
{
    var x= new DisposableObject();
    //stuff
}

void FOO()
{
    using(var x= new DisposableObject())
    {
        //stuff
    }
}
4个回答

7

您应该始终调用Dispose()方法释放需要它的对象。即使对象已被垃圾回收,仍可能存在未释放的非托管资源。调用Dispose()方法(或者像第二个示例中使用using语句)可以确保该对象能够正确地释放其所需的非托管资源。


如果类被正确实现,析构函数将清理这些非托管资源。 - i3arnon
@i3arnon 请看这个链接:https://dev59.com/snA75IYBdhLWcg3wH1XP - itsme86
3
不一定,而且你甚至不能保证最终器会运行于所有对象。 - Servy
@itsme86 如果进程崩溃或卸载时,也不能保证执行 finally 块。当然,尽快处理是首选,但不是强制性的(例如,任务http://blogs.msdn.com/b/pfxteam/archive/2012/03/25/10287435.aspx)。 - i3arnon

3

函数内的所有对象在函数结束时都会消失

对象将保留,但本地引用将消失。当垃圾回收器运行并确定它们不可达时,对象将“消失”。

在无法访问的对象从内存中移除之前,如果已实现,将运行其终结器以清除所有未托管的资源。

问题在于这一切都是不确定的。您永远不知道GC何时运行,在某些情况下,终结器甚至不会被执行。

如果可能的话,应始终调用Dispose方法。

如果想了解更多关于终结器的详细信息,可以阅读这两篇文章:第一部分第二部分


2

对象不会简单地消失。

垃圾收集器(GC)会回收不再被引用的实例。这可能需要时间,因为GC决定何时运行,直到运行时实例才会被处理。

如果此可处理对象有未受控资源并且已正确实现,则这些资源将在终结器中被处理,终结器是一个单线程。

如果您可以接受实例在一段时间内未被处理,并且终结器没有忙碌...那就继续吧。但是最好尽快处理它。


1

在Dispose()方法中设置断点,并使用调试运行这些测试。 TestMethod1没有触发断点,而TestMethod2则可以。

正如其他人所指出的那样,这是由于.Net中GC的工作方式造成的。 如果您要实现IDiisposeable接口,可能需要将类放在using语句中或调用.Dispose(),以便您拥有更可预测的应用程序行为。

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTestProject2
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            var disposable = new DisposableObject();
            disposable.DoSomething();
        }

        [TestMethod]
        public void TestMethod2()
        {
            using (var disposable = new DisposableObject())
            {
                disposable.DoSomething();
            }
        }
    }

    public class DisposableObject : IDisposable
    {
        public void Dispose()
        {
            // dispose here
        }

        public void DoSomething()
        {
            // do something here
        }
    }
}

1
垃圾回收器永远不会调用 Dispose,它会调用终结器,而终结器应该反过来调用 Dispose - Preston Guillot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接