我在框架中使用MEF在运行时动态地组成工作线程“可用处理器”。
有一个要处理的项目队列,并且实例化了大量工作线程(16)。管理队列的类使用了一个ommon CompositionContainer,然后每个worker创建它自己的容器:
using (CompositionContainer container = new CompositionContainer(CompositionContainer)) {
container.ComposeExportedValue<CompositionContainer> (container);
using (Processor.ProcessorSession session = container.GetExport<Processor.ProcessorSession>().Value) {
Data data;
while (_DataQueue.Dequeue(out data)) {
session.ProcessData(data);
}
}
}
我的问题是在Processor.ProcessorSession中,一个DataManager被MEF实例化为一个共享对象 - 这是好的,我希望它在“工作上下文”中是唯一的。遗憾的是,这导致一个DataManager存在,而不是每个子容器一个。顺便说一下,这导致了很多混乱(a.k.a. bugging out)。
错误在哪里?子容器是否只是自动委托给父容器?我该如何阻止它?
顶部只定义了一个目录,对于这个特定的场景,我真的希望避免在这个级别处理自定义目录。
建议的读数?建议的解决方案?
通缉行为: *基本合成容器中没有DataManager固定。 *我希望它在子容器中共享(在示例代码中创建的容器) *但是:每个工作线程都有自己的子容器,因此共享的“上下文”应该是子容器,而不是父容器(即每个线程在ProcessorSession中创建一个DataManager)。
答案 0 :(得分:2)
您需要确定每个工作环境应该共享哪些部分,以及哪些部分应该全局共享。您应该将它们放在单独的目录中,并且父容器应该使用应该全局共享的部分目录,而子容器应该使用具有在工作上下文中应该唯一的部分的目录。
如果没有需要全局共享的部分,那么您根本不需要父子容器关系。只需为每个worker创建一个单独的CompositionContainer。我建议只创建一次目录,因为这有助于提高性能。
如果您确实需要将零件拆分为两个不同的目录,最新MEF预览中的FilteredCatalog可能会对您有所帮助。此外,现在我们正在沿着这些方向开发更多功能(因此希望您不必自己管理拆分目录)。当我们发布具有该功能的新预览时,我们将寻找反馈,因此请观看MEF codeplex网站以及MEF团队成员的一些博客: