Is the default T constructor in your Lazy complex? MEF uses LazyThreadSafetyMode.PublicationOnly , which means that each thread accessing the unified Lazy will generate a new() on T until the first completes initialization. This value is then returned for all threads that are currently accessing .Value , and their own new() instances are discarded. If your constructor is complex (perhaps too much?), You must redefine it by doing minimal construction work and moving the configuration to another method.
You need to think about the method as a whole. If you think:
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(); } }
It is also necessary to consider that if plugins not read-only, you also need to synchronize access to this instance, otherwise it can be changed in another thread, as a result of which your code will crash.
source share