【问题标题】:Thread safety and MEF catalog线程安全和 MEF 目录
【发布时间】:2014-05-03 18:17:51
【问题描述】:

我正在使用 MEF(.Net Framework 中的那个,而不是 System.Composition Nuget)在 asp.net 中执行 DI。由于 MEF 生根 NonShared IDisposable(例如link),我遇到了许多以前的内存泄漏问题

我正在考虑使用子容器来纠正这个问题

  • 子容器创建特定于单个请求的(非共享)部分
  • 包含共享部件的父容器(引用为导出提供程序)

比如:

CompositionContainer GetRequestContainer(CompositionContainer parent, ComposablePartCatalog catalog)
{
    return new CompositionContainer(catalog, parent);
}

最初,我用共享和非共享部件构建了一个目录:为了创建一个只有非共享部件的子容器,我使用 FilteredCatalogs 构建了父 CompositionContainer 的目录,以便过滤后的目录仅包含非共享部分。

这解决了内存泄漏问题,因为我可以在请求结束时 Dispose() 子容器,然后释放我所有的 NonShared IDisposable 对象。伟大的。

但是,调用 childContainer.GetExportValues 会返回重复项,因为父容器目录和子容器目录中都有部分内容


现在我想明确创建 2 个目录

  • 所有共享部件的全局目录
  • 所有非共享部件的本地目录

我怀疑 IDisposable 跟踪是在容器级别,所以我应该安全地传递每个目录的 single 实例,但这就是我想在这里询问并确认的:

目录的单个实例支持所有容器实例是否线程安全

所以 N 并发 WebRequest 实例由 N + 1 个 CompositionContainer 实例(子+父)提供服务,均由 2 个全局目录实例支持。

CompositionContainer parent = new CompositionContainer(Static.Global, CompositionOptions.IsThreadSafe);

CompositionContainer GetRequestContainer(CompositionContainer parent)
{
    return new CompositionContainer(Static.Local, parent);
}

【问题讨论】:

    标签: asp.net multithreading dependency-injection thread-safety mef


    【解决方案1】:

    将同一个目录实例与多个CompositionContainer 实例一起使用是非常安全的(顺便说一句,无论您在创建容器时是否使用CompositionOptions.IsThreadSafe 选项,都是如此)。

    这样做是安全的,因为目录只定义了可以由容器创建的部件的“潜力”,并且不包含任何关于它们是否已被实例化的数据。跟踪此类事情是容器的责任。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-09
      • 2014-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多