私は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");
}
}
https://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspxには、型(アセンブリ)がスレッドセーフであると記載されています。つまり、Assembly.Load(byte [])を含む全体の型が実際にスレッドセーフであることを示します。 – Joeppie
「スレッドセーフ」は、「安全」な動作が何になるかについて書かれている文書がほとんどないため、無意味な用語です。時には「スレッドセーフ」とは、「複数のスレッドからのアクセス時にクラッシュしない」ということだけを意味しますが、ほとんどの場合、その動作についての知識が必要です。恐らく、バイト配列からアセンブリをロードすることは安全です。重複を取得することもありますが、クラッシュは発生しません。これがドキュメントの意味です。通常、「並行」データ構造クラスだけが、安全な振る舞いがどのようなものになるかを文書化する。 –
Lasse、私のシナリオでは、同時のシナリオから異なるアセンブリを読み込みます。スレッドセーフは無意味な用語ではありません。私は他の変数を考慮して検証することができます。確かにスレッドセーフでない場合は、非同期の読み取り操作からスレッドセーフなコレクションを維持し、バイト配列を追加してからこれをループし、アセンブリを1つずつ追加する必要があります。 – Joeppie