と「System.Lazy.LazyThreadSafetyMode」私はこのように私のクラスに異なるアセンブリからの多くの部分をインポートする使用:輸入部品の後MEF
[ImportMany(typeof(IServiceProvider))]
private IEnumerable<Lazy<IServiceProvider, IDictionary<string, object>>> ServiceProviders
{
get;
set;
}
を、サービスプロバイダは、オンデマンドで作成されます。
private IServiceProvider GetServiceProvider(String name)
{
foreach (var serviceProvider in ServiceProviders)
{
String currentName = (String)serviceProvider.Metadata["Name"];
if (currentName == name)
return serviceProvider.Value; // Many threads receive here and try to create new instance.
}
return null;
}
上記のコードでコメントしたように、多くのスレッドはlazy
変数のvalue
(まだ作成されていない場合は、その新しいインスタンスを作成します)を同時に取得しようとします。部品をインポートする際
// Something here...
Dictionary<string, object> metadata = new Dictionary<string,object>();
metadata.Add("Name", "test");
Lazy<IServiceProvider, IDictionary<string, object>> serviceProvider = new Lazy<IServiceProvider, IDictionary<string, object>>(ServiceProviderValueFactory, metadata, System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);
// Now access to 'serviceProvider.Value' creates an instance (if not created yet) in a thread-safe manner.
private IServiceProvider ServiceProviderValueFactory()
{
// Create and return a new instance of 'IServiceProvider'.
}
MEF
オブジェクト作成の心配を取り、私ができますLazy
コンストラクタを使用したい:これはのように
Lazy<T>
は、thread-safe
的にインスタンス(value
)を作成できるようにするコンストラクタを持っていますスレッドセーフなvalue
作成のために私はどのようにわからない。
は実際に私が追加/削除し、コンテナから変更されたプラグインを置き換えるために、 'DirectoryCatalog'を更新する必要があります:
ExportServices
では、ハードとして符号化されます。これはスレッドセーフですか? – Xaqron
@Xaqronはい、スレッドの安全性に反するでしょう。これがサーバーサイドアプリケーションの場合は、将来のすべての要求に使用される新しいカタログとコンテナを作成し、現在の要求を完了するために現在のコンテナを使用できるようにするのが最善の方法です。クライアントアプリケーションの場合は、おそらくカタログの更新を行う前にコンテナにアクセスする可能性のある他のスレッドで作業を一時停止する必要があります。 –