2012-02-10 2 views
2

私はAppDomain.AssemblyResolveイベントに接続してから、Assembly.Load(byte[])を呼び出してアセンブリを読み込みます。Assembly.Load(byte [])はスレッドセーフではありませんか?

これが複数のスレッドから実行された場合、重複するアセンブリがロードされることになります。しかし、Assembly.LoadFromまたはAssembly.LoadFileと呼んだ場合、この問題は発生しません。

これはAssembly.Loadを使用する既知のqwerkかどうか疑問に思っていましたか?スレッドセーフではないので、このシナリオを処理するために余分なコードを追加する必要がありますか?あなたは、彼らがファイルシステムを使用しているので、LoadFromとLoadFileが方法が、そこに自分の同期を持っているケースを作ることができ、これらのメソッドの実装の詳細を見てみると完全なコードは以下の

...

[TestFixture] 
public class Tester 
{ 
    [Test] 
    public void Run() 
    { 
     var currentDomain = AppDomain.CurrentDomain; 
     currentDomain.AssemblyResolve += ResolveAssembly; 

     var thread1 = new Thread(LoadAssembly); 
     var thread2 = new Thread(LoadAssembly); 

     thread1.Start(); 
     thread2.Start(); 
     thread1.Join(); 
     thread2.Join(); 
     var assemblies = currentDomain.GetAssemblies(); 
     Assert.AreEqual(1, assemblies.Count(x => x.GetName().Name == "AssemblyToReference")); 
    } 

    Assembly ResolveAssembly(object sender, ResolveEventArgs args) 
    { 
     //This works 
     //return Assembly.LoadFile(@"PathToAssembly"); 

     //This works 
     //return Assembly.LoadFrom(@"PathToAssembly"); 

     //This does not work 
     return Assembly.Load(File.ReadAllBytes(@"PathToAssembly")); 
    } 

    void LoadAssembly() 
    { 
     Assembly.Load("AssemblyToReference"); 
    } 
} 

答えて

-1

。つまり、両方のメソッドは、ファイルを読み込む前に排他ロックを取得します。これはもちろん、メモリにあるアセンブリでは当てはまりません。

(そして、MSDNは十分に言う、おそらく、スレッドセーフであること、これらの方法の声明を、持っていない?:))

+0

https://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspxには、型(アセンブリ)がスレッドセーフであると記載されています。つまり、Assembly.Load(byte [])を含む全体の型が実際にスレッドセーフであることを示します。 – Joeppie

+1

「スレッドセーフ」は、「安全」な動作が何になるかについて書かれている文書がほとんどないため、無意味な用語です。時には「スレッドセーフ」とは、「複数のスレッドからのアクセス時にクラッシュしない」ということだけを意味しますが、ほとんどの場合、その動作についての知識が必要です。恐らく、バイト配列からアセンブリをロードすることは安全です。重複を取得することもありますが、クラッシュは発生しません。これがドキュメントの意味です。通常、「並行」データ構造クラスだけが、安全な振る舞いがどのようなものになるかを文書化する。 –

+0

Lasse、私のシナリオでは、同時のシナリオから異なるアセンブリを読み込みます。スレッドセーフは無意味な用語ではありません。私は他の変数を考慮して検証することができます。確かにスレッドセーフでない場合は、非同期の読み取り操作からスレッドセーフなコレクションを維持し、バイト配列を追加してからこれをループし、アセンブリを1つずつ追加する必要があります。 – Joeppie

0

ドキュメントは、私は間違いなく同じアセンブリを複数回ロードするコピー/新しいインスタンスをもたらすことができることを示している、そう同じアセンブリまたはアセンブリの異なるバージョンで2回呼び出すことは避けられます。

これ以外にも、https://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspxには、型(アセンブリ)がスレッドセーフであることが記載されています。つまり、Assembly.Load(byte [])を含む全体の型が実際にスレッドセーフであることを示します。複数のスレッドがアクセスしたときに実装競合状態の自由であることが保証されています。安全が

  • スレッド:このトピックのearier情報が与えられ

    は、私がする必要が(wikipediaあたりなど)安全スレッドを定義感じます同時に。

これは、あなたが安全に、複数のスレッドからそれを使用できることを意味しますが、操作はidempotentではないことに注意する必要があります。それを2回呼び出すと、1つではなく2つの結果が得られます。

概念上、上記の問題が発生した場合、のコード Assembly.Load(byte [])は実際にはスレッドセーフではありません。

関連する問題