由于.NET有一个垃圾收集器为什么我们需要终结器/析构/处置,模式? [英] Since .NET has a garbage collector why do we need finalizers/destructors/dispose-pattern?

查看:206
本文介绍了由于.NET有一个垃圾收集器为什么我们需要终结器/析构/处置,模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我理解正确的话后,我的.NET运行时会经常清理。所以,如果我创建新的对象,我停在我code引用它们,运行时会清理这些对象并释放它们占用的内存。

If I understand correctly the .net runtime will always clean up after me. So if I create new objects and I stop referencing them in my code, the runtime will clean up those objects and free the memory they occupied.

既然是这样的话那么为什么某些对象需要有一个析构函数或处理方法?不会运行后,他们清理时,他们不再被引用的?

Since this is the case why then do some objects need to have a destructor or dispose method? Won’t the runtime clean up after them when they are not referenced anymore?

推荐答案

需要终结,以保证稀缺资源的释放回系统,例如文件句柄,插座,内核对象等。由于终结始终运行在年底对象的生活,它的​​指定地点释放这些句柄。

Finalizers are needed to guarantee the release of scarce resources back into the system like file handles, sockets, kernel objects, etc. Since the finalizer always runs at the end of the objects life, it’s the designated place to release those handles.

处置模式是用来提供资源确定性的破坏。由于.NET运行时垃圾回收具有不确定性(这意味着你不能确定时,运行时将收集旧物,并呼吁他们的终结),需要一种方法来确保系统资源的确定性释放。因此,当你正确地贯彻落实处置模式您所提供的资源,并在案件确定的发行,其中消费者是不小心,不处置的对象,终结将清理对象。

The Dispose pattern is used to provide deterministic destruction of resources. Since the .net runtime garbage collector is non-deterministic (which means you can never be sure when the runtime will collect old objects and call their finalizer), a method was needed to ensure the deterministic release of system resources. Therefore, when you implement the Dispose pattern properly you provide deterministic release of the resources and in cases where the consumer is careless and does not dispose the object, the finalizer will clean up the object.

为什么处置需要可能是一个快速和肮脏的记录方法,一个简单的例子:

A simple example of why Dispose is needed might be a quick and dirty log method:

public void Log(string line)
{
    var sw = new StreamWriter(File.Open(
        "LogFile.log", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None));

    sw.WriteLine(line);

    // Since we don't close the stream the FileStream finalizer will do that for 
    // us but we don't know when that will be and until then the file is locked.
}

在上面的例子中,该文件将保持锁定状态,直到垃圾收集器调用的的StreamWriter 对象的终结。这presents一个问题,因为,在此期间,该方法可能会被再次调用写日志,但这次将失败,因为该文件仍然锁定。

In the above example, the file will remain locked until the garbage collector calls the finalizer on the StreamWriter object. This presents a problem since, in the meantime, the method might be called again to write a log, but this time it will fail because the file is still locked.

正确的方法是处置的对象使用它完成时:

The correct way is to dispose the object when are done using it:

public void Log(string line)
{
    using (var sw = new StreamWriter(File.Open(
        "LogFile.log", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))) {

        sw.WriteLine(line);
    }

    // Since we use the using block (which conveniently calls Dispose() for us)
    // the file well be closed at this point.
}

BTW,技术上终结和析构函数意味着同样的事情;我做preFER调用C#析'终结',否则他们往往给人以C ++的析构函数,它不像C#中,是确定性的迷惑。

BTW, technically finalizers and destructors mean the same thing; I do prefer to call c# destructors 'finalizers' since otherwise they tend to confuse people with C++ destructors, which unlike C#, are deterministic.

这篇关于由于.NET有一个垃圾收集器为什么我们需要终结器/析构/处置,模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆