c# - 处理托管资源时堆栈溢出

标签 c# .net unity-container stack-overflow idisposable

我有一个用于 Unity IoC 容器的简单包装器(临时使用服务定位器 [anti-]Pattern 将 DI 引入遗留代码库),并且自 IUnityContainer在 Unity 中实现 IDisposable我也想通过包装器公开它。

包装器非常简单:

public class IoCContainer : IIoCContainer
{
    private IUnityContainer _container;

    public IoCContainer(IUnityContainer container)
    {
        _container = container;
    }

    public T Resolve<T>()
    {
        return _container.Resolve<T>();
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~IoCContainer()
    {
        Dispose(false);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
            if (_container != null)
            {
                _container.Dispose();
                _container = null;
            }
    }
}

IIoCContainer是域接口(interface),它只有 T Resolve<T>()在上面,当然还有IDisposable .因此,该方法下面的所有内容都只是 IDisposable 的实现。 as I found it on MSDN .

然而,当.Dispose()在此对象上调用(例如退出 using block 时),一个 StackOverflowException被提出。调试,看起来调用堆栈在以下之间重复:

  • Dispose()在这个类上被调用
  • 调用Dispose(true)在这门课上
  • 调用Dispose()IUnityContainer
  • 调用Dispose()在这门课上

enter image description here

在这种情况下,我可以解决这个问题,方法是放置 bool类上的标志,将其设置在 Dispose() 的第一行,并在 Dispose(bool) 中检查它, 所以递归在它的第二次迭代结束。但是为什么首先会发生这种情况?我只能假设我错过了一些明显的事情或者误解了有关资源处理的事情。但是什么?

最佳答案

这是 UnityContainerIDisposable 的实现。很明显,您不能处置您的父容器。它将遍历所有注册并在它们也是 IDisposable 时处理它们。看一看:

protected virtual void Dispose(bool disposing) 
{ 
   if (disposing) 
   { 
       if (lifetimeContainer != null) 
       { 
           lifetimeContainer.Dispose(); 
           lifetimeContainer = null; 

           if (parent != null && parent.lifetimeContainer != null) 
           { 
               parent.lifetimeContainer.Remove(this); 
           } 
       } 

       extensions.OfType<IDisposable>().ForEach(ex => ex.Dispose()); 
       extensions.Clear(); 
   } 
} 

关于c# - 处理托管资源时堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41286181/

相关文章:

c# - 使用 C# 的 VMware vCenter API - InitiateFileTransferToGuest 失败

c# - 在一个时间跨度内循环

c# - List<T> 的手写映射器

c# - Unity 2.0 和处理 IDisposable 类型(尤其是使用 PerThreadLifetimeManager)

c# - 有没有办法验证字典的值

c# - 隐藏基类中存在的方法

c# - 如何将样式放在单独的 .xaml 文件中

.net - 执行集成测试时如何从 .Net 应用程序中隔离坏的 COM 组件 (HP Quality Center 10.0)

.net - 在 Unity 中调用站点拦截方法的完整堆栈跟踪

c# - 具有 Entity Framework 的 IOC