我有一个奇怪的问题,我找不到明确的答案,即使有很多线程围绕着同一个问题。
问题:如果我将对象设置为 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 的帖子是关于该主题的一个很好的读物:
关于c# - 将对象设置为 null 是否确定性地处置对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20420977/