Assembly.Load (byte []) не является потокобезопасным? - PullRequest
2 голосов
/ 10 февраля 2012

Я присоединяюсь к событию AppDomain.AssemblyResolve , а затем вызываю Assembly.Load (byte []) для загрузки сборки.

Похоже, что если это будет сделано из нескольких потоков, я могу получить дубликаты сборок. Однако если я вызываю Assembly.LoadFrom или Assembly.LoadFile , эта проблема не возникает.

Мне просто интересно, является ли это известным qwerk использования Assembly.Load? Разве это не потокобезопасно, и мне нужно добавить дополнительный код для обработки этого сценария?

Полный код следует ...

[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");
    }
}

Ответы [ 2 ]

1 голос
/ 12 января 2017

Документация действительно указывает, что загрузка одной и той же сборки несколько раз может привести к копированию / новым экземплярам, ​​поэтому я определенно не буду вызывать ее дважды для одной и той же сборки или для разных версий сборки.

Помимо этого, https://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspx указывает, что тип (сборка) является потокобезопасным.Это означает, что весь тип, включая Assembly.Load (byte []), действительно безопасен для потоков.

Учитывая более раннюю информацию в этой теме, я чувствую необходимость определить потокобезопасность (согласно wikipedia ):

  • Потокобезопасен: Реализация гарантированно не содержит условий гонки при одновременном доступе к нескольким потокам.

Это означает, что вы можете безопасно использовать его из нескольких потоков, но вы должны знать, что операция не является идемпотентная ;дважды вызывая его, вы получите два результата, а не один.

Концептуально, если вышеописанное является проблемой, код, который использует Assembly.Load (byte []), фактически непотокобезопасен.

0 голосов
/ 10 февраля 2012

Рассматривая подробности реализации этих методов, вы можете убедиться, что методы LoadFrom и LoadFile, поскольку они используют файловую систему, имеют свою синхронизацию там.То есть оба метода получают монопольную блокировку файла перед его чтением. Это, конечно, не относится к сборке, находящейся в памяти.

(И в MSDN нет заявления о том, что эти методы поточно-ориентированыможет быть, этого достаточно? :))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...