线程安全延迟实例化使用MEF [英] Thread-Safe lazy instantiating using MEF
问题描述
// Member Variable
private static readonly object _syncLock = new object();
// Now inside a static method
foreach (var lazyObject in plugins)
{
if ((string)lazyObject.Metadata["key"] = "something")
{
lock (_syncLock)
{
// It seems the `IsValueCreated` is not up-to-date
if (!lazyObject.IsValueCreated)
lazyObject.value.DoSomething();
}
return lazyObject.value;
}
}
在这里,我需要同步每个循环的访问。有许多线程迭代这个循环,并根据键
,他们正在寻找,一个懒惰的实例被创建并返回。
Here I need synchronized access per loop. There are many threads iterating this loop and based on the key
they are looking for, a lazy instance is created and returned.
lazyObject
不应该创建更多的一次。虽然懒
类是这样做的,尽管所使用的锁,在高线程我有多个实例创建的(我跟踪这个用互锁.Increment
在挥发性
静态INT
和地方记录它)。问题是我没有获得的懒
和 MEF
定义定义如何使用懒人
类创建对象。我应该注意 CompositionContainer中
在一个已经使用的构造线程安全的选择。
lazyObject
should not be created more that one time. Although Lazy
class is for doing so and despite of the used lock, under high threading I have more than one instance created (I track this with a Interlocked.Increment
on a volatile
static int
and log it somewhere). The problem is I don't have access to definition of Lazy
and MEF
defines how the Lazy
class create objects. I should notice the CompositionContainer
has a thread-safe option in constructor which is already used.
我的问题:
1)为什么锁不起作用?
1) Why the lock doesn't work ?
2)我应该使用锁的阵列,而不是性能改进一把锁?
2) Should I use an array of locks instead of one lock for performance improvement ?
推荐答案
是 T的默认构造函数
在你的懒
复杂? MEF使用 LazyThreadSafetyMode.PublicationOnly
这意味着每个线程访问unitialised 懒
将生成一个新( )
在 T
直到第一次完成初始化。然后,该值返回为被丢弃当前访问的所有线程 .value的
和自己的新()
实例。如果你的构造是复杂的(也许做得太多?),你应该重新定义为做最少的建设工作和移动配置的另一种方法。
Is the default constructor of T
in your Lazy
complex? MEF uses LazyThreadSafetyMode.PublicationOnly
which means each thread accessing the unitialised Lazy
will generate a new()
on T
until the first to complete the initialisation. That value is then returned for all threads currently accessing .Value
and their own new()
instances are discarded. If your constructor is complex (perhaps doing too much?) you should redefine it as doing minimal construction work and moving configuration to another method.
您需要思考的方法作为一个整体。如果你考虑:
You need to think about the method as a whole. Should you consider:
public IPlugin GetPlugin(string key)
{
mutex.WaitOne();
try
{
var plugin = plugins
.Where(l => l.Metadata["key"] == key)
.Select(l => l.Value);
.FirstOrDefault();
return plugin;
}
finally
{
mutex.ReleaseMutex();
}
}
您还需要考虑,如果插件
不是只读的,那么你需要同步访问该实例太多,否则很可能在另一个线程上进行修改,从而导致你的代码摔倒。
You also need to consider that if plugins
is not read-only then you need to synchronise access to that instance too, otherwise it may be modified on another thread, causing your code to fall over.
这篇关于线程安全延迟实例化使用MEF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!