Проблема с выгрузкой CollectibleAssemblyLoadContext, сбой программы во время сборки мусора - PullRequest
0 голосов
/ 22 июня 2019

При первой публикации здесь, надеюсь, что вы, ребята, поможете мне.

Я создаю приложение, которое может загружать и выгружать сборки без перезапуска приложения.

Загрузка и выгрузкасборки работает без проблем в первый раз, но при загрузке и выгрузке DLL, которая уже была выгружена, прежде чем я получаю сбой приложения.Иногда dll будет загружаться / выгружаться пару раз, прежде чем произойдет сбой приложения, но он всегда падает на одной и той же строке (GC.WaitForPendingFinalizers ();).

Я использую .net core 3 preview 6 вvisual studio prof 2019 версия 16.1.3.

Я что-то не так делаю или это, возможно, ошибка в ядре .net?

Ниже приведен пример кода, в котором возникла проблема.

using System;
using System.Reflection;
using System.Runtime.Loader;

namespace ConsoleApp1 {
    class Program {

        static void Main() {
            try {
                for (int index = 0; index < 99; index++) {
                    WeakReference weakReference = Load(@"C:\TestAssembly.dll"); ;
                    for (var i = 0; i < 8 && weakReference.IsAlive; i++) {
                        GC.Collect();
                        Console.WriteLine($"\tGC.Collect done!");
                        GC.WaitForPendingFinalizers();
                        Console.WriteLine($"\tGC.WaitForPendingFinalizers done!");
                    }
                    Console.WriteLine(Environment.NewLine + $"Unloading assembly: {(!weakReference.IsAlive ? "success" : "failed")}!");
                }
            } catch (Exception exception) {
                Console.WriteLine(exception.Message);
            }
        }

        public class CollectibleAssemblyLoadContext : AssemblyLoadContext {
            public CollectibleAssemblyLoadContext() : base(isCollectible: true) { }
        }

        private static WeakReference Load(string assemblyPath) {
            CollectibleAssemblyLoadContext context = new CollectibleAssemblyLoadContext();
            Assembly assembly = context.LoadFromAssemblyPath(assemblyPath);

            // Do something with loaded assembly
            // .......

            context.Unload();
            Console.WriteLine($"Unloading assembly");

            return new WeakReference(context);
        }
    }
}


using System;

namespace TestAssembly {
    public class Class1 {

    }
}

Вывод:

Выгрузка сборки
GC.Collect выполнено!
GC.WaitForPendingFinalizers выполнено!
GC.Collect выполнено!
GC.WaitForPendingFinalizers выполнено!

Выгрузка сборки: success!
Выгрузка сборки
GC. Сбор завершен!

С последующим сбоем программы: HRESULT = 0x80070057.ErrorCode = 0x0.

...