c# - 将对象设置为 null 是否确定性地处置对象?

标签 c#

我有一个奇怪的问题,我找不到明确的答案,即使有很多线程围绕着同一个问题。

问题:如果我将对象设置为 null,是否会导致确定性地调用 dispose 方法(已实现)?例如在下面的代码中,通过将 pricingEnvironment 对象设置为 null,是否会立即调用 Dispose?我知道如果没有调用 Dispose,终结器将在某个时候为 pricingEnvironment 对象启动。

代码:

public interface IPricingService
    {
        double GetPrice(string instrument);
    }

    public interface IPricingEnvironment:IDisposable
    {
        void Initialize();
    }

    public class PricingEnvironment : IPricingEnvironment
    {
        public void Dispose()
        {
            DisposeObject();
        }

        public void Initialize()
        {
            //initialize something leaky
        }

        private void DisposeObject()
        {
            //release some leaky unmanaged resource
        }

        ~PricingEnvironment()
        {
            DisposeObject();
        }
    }

    public class PricingService:IPricingService, IDisposable
    {
        private IPricingEnvironment pricingEnvironment;
        public PricingService()
        {
            pricingEnvironment = new PricingEnvironment();
        }
        public double GetPrice(string instrument)
        {
            pricingEnvironment.Initialize();
            return 1d;
        }

        public void Dispose()
        {
            //Will this dispose the leaky resource used by pricing environment deterministically?
            pricingEnvironment = null;
        }
    }

谢谢, -迈克

最佳答案

在 .NET 中无法保证终结器会被调用。垃圾收集器可能根本不调用它(例如,因为垃圾收集器根本不需要释放内存),并且在一个终结器抛出异常的情况下,其他终结器将不会执行(参见 MSDN )。如果您在对象上调用 SuppressFinalizer,您甚至可以抑制终结器。

话虽如此,当然也不能保证终结器会立即被调用(它可能会在很久以后被调用或根本不被调用)。

您应该显式调用 Dispose 或使用 using 语句,以便您的对象得到正确处理。作为安全网,您仍然可以从终结器调用 Dispose。事实上,MSDN 中的示例也证明了这是最佳实践。 .

Raymond Chen 的帖子是关于该主题的一个很好的读物:

Everybody thinks about garbage collection the wrong way

关于c# - 将对象设置为 null 是否确定性地处置对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20420977/

相关文章:

没有 Visual Studio 的 C# 6.0

c# - WebAPI2 Json.Net 必需属性未正确添加 ModelState 错误

c# - 在 C# 中如何检查某个日期是否已经过去?

c# - 我应该从哪里升级到来自 .NET 2.0/WinForms 背景的复杂 .NET 3.5 和 WPF 应用程序?

c# - 在单声道 (mac) 中编译 C# visual studio 控制台应用程序

c# - 解码时 Hashids 在 .NET 中不起作用

c# - 添加 .csv 文件作为资源文件并在代码中访问它

c# - DataGridTextColumn 可见性绑定(bind)

C# - 如何使用正则表达式替换 NULL 字符?

c# - .NET - 用单个 using 语句替换嵌套的 using 语句