asp.net - 线程安全和 MEF 目录

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

我正在使用MEF(.Net Framework 中的MEF,而不是System.Composition Nuget)在asp.net 中进行DI。我遇到了内存泄漏,就像许多人以前遇到的那样,由于 MEF rooting NonShared IDisposable (例如 link )

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

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

所以类似:

CompositionContainer GetRequestContainer(CompositionContainer parent, ComposablePartCatalog catalog)
{
    return new CompositionContainer(catalog, parent);
}
<小时/>

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

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

但是,调用 childContainer.GetExportValues 会返回重复项,因为存在来自父容器目录和子容器目录的部分

<小时/>

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

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

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

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

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

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

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

最佳答案

将同一个目录实例与多个 CompositionContainer 实例一起使用是完全安全的(顺便说一句,无论您是否在以下情况下使用 CompositionOptions.IsThreadSafe 选项,这都是正确的)创建容器)。

这样做是安全的,因为目录仅定义了容器可以创建的部件的“潜力”,并且不保存有关它们是否已实例化的任何数据。容器有责任跟踪这些事情。

关于asp.net - 线程安全和 MEF 目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23448218/

相关文章:

java - 如何在调用notify之前确保所有线程都已完成?

c# - Dotnet Core 是否实现组合根发现?

c# - 在 Sitecore 中识别页面请求的简单方法

asp.net - 为什么这个用于 ASPX 站点的 ScraperWiki 只返回相同的搜索结果页面?

c# - ASP.Net 中的图形 (c#)

multithreading - readMVar 不会在 putMVar 上唤醒

c# - 当 UI 线程被阻塞时确保 Storyboard 动画流畅

spring - 在测试时在 Grails 中注册替代/模拟服务实现?

java - Guice:场注入(inject)的影响

asp.net - 将 visual studio 2015 中的 asp.net 5 发布到 linux