2012-02-07 39 views
3

私は、コードのParallel.ForEachブロック内で同時にたくさんのファイルを読んでいる私のプロジェクトでユニティ2.0を使用しています:UNITY:スレッドセーフなContainer.Resolve()関数をコンストラクタインジェクションで実装する方法は?

Parallel.ForEach(files, currentFile => 
{ 
    using(IMsBuildProjectLoader msBuildProject = Container.Resolve<IMsBuildProjectLoader>(new ParameterOverride("projectFileName", currentFile))) 
    { 
     // file processing 
    } 
} 

解決(新ParameterOverride(「projectFileName」、currentFile)機能は時々ResolutionFailedExceptionを投げる:

ResolutionFailedException: Resolution of the dependency failed, 
type = "Porthus.Build.Common.Interfaces.IMsBuildProjectLoader", name = "(none)". 
Exception occurred while: Calling constructor XXX.Build.Common.Types.MsBuildProjectLoader(System.String projectFileName). 
Exception is: ArgumentException - Item has already been added. Key in dictionary: 'xxx' Key being added: 'xxx' 

同じファイルを同時にロードされたときにこれがある - 機能が同時に同じパラメータを持つ2つのIMsBuildProjectLoaderインスタンスを作成して解決することは、(files.Distinctによって解決することはできません。 )上記のコードは、私の問題を説明するコード例です。

質問はです:どのようにスレッドセーフなUnityContainer.Resolve関数を実装するのですか?いくつかのUnityエクステンションクラスを使ってそれを行うことは可能ですか?

IMsBuildProjectLoader

public interface IMsBuildProjectLoader : IDisposable 
{ 
} 

MsBuildProjectLoader:MsBuildProjectLoaderがこのように登録されている

public class MsBuildProjectLoader : Project, IMsBuildProjectLoader 
{ 
    public MsBuildProjectLoader(string projectFileName) 
     : base() 
    { 
     // Load the contents of the specified project file. 
     Load(projectFileName); 
    } 
} 

container.RegisterType<IMsBuildProjectLoader, MsBuildProjectLoader>(); 
+5

これはあなたの質問に直接答えませんが、間違っていると思われます。あなたのクラスにはIMsBuildProjectLoaderが注入されていなければなりません。ループでは、ファイル名をパラメータとするIMsBuildProjectLoaderのメソッドを呼び出す必要があります。スレッドセーフは、IMsBuildProjectLoaderの実装に組み込まれます。私の$ 0.02。 – BFree

+0

はい、これは別のオプションです。ありがとう – Ludwo

答えて

0

解決が実際にスレッドです安全な(またはMicrosoft P & Pの人たち)。 おそらくスレッドセーフではないのは、MsBuildProjectLoaderの実装です。具体的には、そのコンストラクタです。 あなたは、おそらくあなたは負荷の実装が含まれていませんでしたが、例外に応じて、私はそれが共有を操作すると仮定するのと同じ非同期に単に新しいを使用してMsBuildProjectLoaderの新しいインスタンスを作成することによって、

を同じ問題がつまずくでしょうまたは静的辞書をスレッドセーフではありません。 この場合、その辞書スレッドを安全にする必要があります(たとえば、ConcurrentDictionaryに置き換える)。

関連する問題