【发布时间】:2014-01-16 07:25:27
【问题描述】:
我有以下代码:
public class Temp<T, TMetadata>
{
[ImportMany]
private IEnumerable<Lazy<T, TMetadata>> plugins;
public Temp(string path)
{
AggregateCatalog aggregateCatalog = new AggregateCatalog();
aggregateCatalog.Catalogs.Add(new DirectoryCatalog(path));
CompositionContainer container = new CompositionContainer(aggregateCatalog);
container.ComposeParts(this);
}
public T GetPlugin(Predicate<TMetadata> predicate)
{
Lazy<T, TMetadata> pluginInfo;
try
{
pluginInfo = plugins.SingleOrDefault(p => predicate(p.Metadata));
}
catch
{
// throw some exception
}
if (pluginInfo == null)
{
// throw some exception
}
return Clone(pluginInfo.Value); // -> this produces errors
}
}
我有一个Temp 对象,我从多个线程调用GetPlugin()。有时我会遇到奇怪的构图错误,我没有找到重现的方法。例如:
"System.InvalidOperationException: Stack empty.
at System.Collections.Generic.Stack`1.Pop()
at System.ComponentModel.Composition.Hosting.ImportEngine.TrySatisfyImports(PartManager partManager, ComposablePart part, Boolean shouldTrackImports)
at System.ComponentModel.Composition.Hosting.ImportEngine.SatisfyImports(ComposablePart part)
at System.ComponentModel.Composition.Hosting.CompositionServices.GetExportedValueFromComposedPart(ImportEngine engine, ComposablePart part, ExportDefinition definition)
at System.ComponentModel.Composition.Hosting.CatalogExportProvider.GetExportedValue(CatalogPart part, ExportDefinition export, Boolean isSharedPart)
at System.ComponentModel.Composition.ExportServices.GetCastedExportedValue[T](Export export)
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at Temp`2.GetPlugin(Predicate`1 predicate)..."
可能是什么原因以及如何解决此代码?
【问题讨论】:
-
您是否尝试过在 try 块中使用
lock语句? -
@LueTm 不,我不能经常重现这个问题,所以我想了解发生了什么以及为什么......我不能只是尝试看看会发生什么跨度>
-
我猜是比赛条件。
-
@LueTm 我正在考虑这个问题,因为错误是不同的、随机的并且发生在 MEF 内部......不是线程安全的对象通常会表现出这种行为
-
好吧,您(可能)多次迭代序列,这通常不是一个好兆头,您(可能)每个项目多次调用谓词,这可能是一个问题。我们需要知道lazy's 的
IEnumerable实际代表什么,谓词在做什么,但最重要的是,我们需要了解lazy's 是如何创建的,因为这就是您的根本问题的根源,正在评估他们的价值。不知道它们来自哪里,我们不可能知道它们有什么问题。
标签: c# .net multithreading thread-safety mef