Немає AppDomains у .NET Core! Чому?


86

Чи є серйозна причина, чому Microsoft вирішила не підтримувати AppDomains у .NET Core?

AppDomains особливо корисні при створенні тривалих серверних додатків, де ми можемо захотіти витончено оновити збірки, завантажені сервером, без вимкнення сервера.

Без AppDomains, як ми збираємося замінити наші збірки в тривалому процесі сервера?

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

Без AppDomains вищезазначений сценарій неможливий.

Я бачу аргумент, який може говорити про використання концепції хмари віртуальних машин для обробки змін збірки, а також про відсутність додаткових витрат на AppDomains. Але чи так думає чи говорить Microsoft? або вони мають конкретну причину та альтернативи для вищезазначених сценаріїв?


9
Але .NET Core 5 не є .NET Framework. Це не майбутня версія .NET CLR 4.6, але інша річ, тоді не хвилюйтеся, AppDomain тут залишиться.
Адріано Репетті

2
Я бачу це, але якщо Microsoft стверджує, що .NET Core 5 буде багатоплатформою (Windows / Linux / Unix), то мені цікаво, чому вони хочуть видалити таку основну функцію, як AppDomain.
Aditya Pasumarthi

3
Я думаю (але це лише моя думка) їх важче впровадити багатоплатформно, вони уповільнюють багато речей та додають складності. Не так багато людей ними користуються (принаймні більшість людей не роблять цього безпосередньо). Якщо вони вам не потрібні, ви можете використовувати .NET Core. Якщо вони вам потрібні ... не використовуйте їх (подумайте ReFS проти NTFS). Просто .NET Core - це не майбутнє .NET (поки що), а окремий проект. Можливо, робочий стіл, але точно не шлях міграції або альтернатива 1: 1 (принаймні зараз).
Адріано Репетті

@AdrianoRepetti: Розгляньте можливість додати це як відповідь, оскільки я вважаю, що це корисно як таке.
Патрік Хофман,

@PatrickHofman - це лише моя думка (2-й коментар), я міг би відповісти як wiki-спільнота, але я залишаю цей обов'язок комусь із більш вільною англійською мовою!
Адріано Репетті

Відповіді:


50

Суть підмножини .NETCore полягала в тому, щоб встановити .NET невеликим . І легко переносити. Ось чому ви можете, скажімо, запустити додаток Silverlight як на Windows, так і на OSX і не довго чекати, коли відвідуєте веб-сторінку. Завантаження та встановлення повного середовища виконання та фреймворку займає кілька секунд.

Зберігаючи його маленьким, неминуче потрібно вирізати особливості. Віддалення було дуже високим у цьому списку, це досить дорого. В іншому випадку добре прихований, але ви можете, наприклад, побачити, що делегати більше не мають функціонального методу BeginInvoke (). Що також додало AppDomain до списку скорочень, ви не можете запускати код у домені програми без підтримки віддаленого доступу. Отже, це цілком за задумом.


12
IMHO це не має нічого спільного з розміром, але з тим фактом, що CoreCLR не має сильних імен, і, отже, має нову систему злиття та новий спосіб розглянути, що таке збірка, її ідентичність та де вона завантажена, означає, що appdomain як контейнер більше не є корисним.
Франс Бума

7
Хм, ні. Зберігаючи розмір завантаження до 6,6 МБ, звичайно, потрібно було видалити більше однієї функції.
Ганс Пасант,

7
AppDomains можуть бути корисними в повному обсязі .NET, навіть якщо ви не використовуєте сильні імена. (Наприклад, здатність AppDomains забезпечувати ізоляцію несправностей не залежить від сильних імен.) Отже, видалення сильного іменування не може бути причиною для видалення AppDomains.
Ян Гріффітс,

5
Я збентежений. Яке відношення між .Net Core та Silverlight?
svick

10
Програмісти, як правило, вважають, що .NETCore є новим. Корпорація Майкрософт робить дуже мало, щоб розвіяти це поняття, не менш, змінивши номер версії 5.0 на 1.0. CoreCLR існував дуже давно, почав життя як середовище виконання .NET Compact. Silverlight та середовище виконання WinRT / UWP є важливим застосуванням для нього до того, як вони відкрили його. Найкраща версія для виконання, яку вже було перенесено на OSX та різні мобільні процесори WinCE.
Ганс Пассант,

46

Оновлення для .NET Standard 2 та .NET Core 2

У .NET Standard 2 там єAppDomain клас . Однак багато частин цього API створюватиме .NET Core.PlatformNotSupportedException

Основна причина, що вона все ще існує, полягає в основних речах, таких як реєстрація обробленого обробника винятків, який буде працювати.

Стандартне поширене запитання щодо .NET містить таке пояснення :

Чи є AppDomain частиною .NET Standard?

Тип AppDomain є частиною .NET Standard. Не всі платформи підтримуватимуть створення нових доменів програм, наприклад, .NET Core не буде, тому метод AppDomain.CreateDomain, доступний у .NET Standard, може викликати PlatformNotSupportedException.

Основною причиною того, що ми виставляємо цей тип у .NET Standard, є те, що використання досить велике і, як правило, не пов’язане зі створенням нових доменів додатків, а для взаємодії з поточним доменом програми, наприклад, реєстрації не оброблюваного обробника винятків або запиту базового каталогу програми .

Окрім цього, головна відповідь та інші відповіді також добре пояснюють, чому основну частину AppDomain все-таки вирізали (наприклад, викиди не підтримується).


20

Домени додатків

Чому його припинено? AppDomains вимагають підтримки під час виконання і, як правило, досить дорогі. Хоча він все ще реалізований CoreCLR, він недоступний у .NET Native, і ми не плануємо додавати цю можливість там.

Що я повинен використовувати замість цього? Домени App використовувались для різних цілей. Для ізоляції коду ми рекомендуємо процеси та / або контейнери. Для динамічного завантаження збірок ми рекомендуємо новий клас AssemblyLoadContext.

Джерело з блогу MSDN


Одне питання, що ви маєте на увазі під For code isolation, we recommend processes and/or containers... Чи є контейнер API у ядрі .net?
Ivandro Jao

@IvandroIsmael, вони означають "розділити ваш єдиний додаток / модуль на окремі взаємодіючі програми / модулі / процеси / контейнери" (найімовірніше - на мікросервіси), тобто рефакторинг вашого додатка, щоб він не використовував AppDomains для ізоляції коду
вибух

10

Одного разу я почув, що розвантаження збірок буде ввімкнено без використання доменів. Я думаю, що System.Runtime.Loader.AssemblyLoadContextтип у System.Runtime.Loader.dll пов'язаний з цією роботою, але я не бачу там нічого, що дозволяє розвантажувати.


5

Я чув про стан спільноти чи про деякі розмови Microsoft, що функція ізоляції AppDomains краще обробляється процесами (а насправді загальним шаблоном на інших платформах), і розвантаження справді планується як звичайна функція, не пов’язана з AppDomains.


5

Вам більше не потрібні AppDomains, тепер у вас є LoadContexts:

public class CollectibleAssemblyLoadContext 
    : AssemblyLoadContext
{
    public CollectibleAssemblyLoadContext() : base(isCollectible: true)
    { }
 
    protected override Assembly Load(AssemblyName assemblyName)
    {
        return null;
    }
}

byte[] result = null; // Assembly Emit-result from roslyn
System.Runtime.Loader.AssemblyLoadContext context = new CollectibleAssemblyLoadContext();
System.IO.Stream ms = new System.IO.MemoryStream(result);
System.Reflection.Assembly assembly = context.LoadFromStream(ms);


System.Type programType = assembly.GetType("RsEval");
MyAbstractClass eval = (MyAbstractClass )System.Activator.CreateInstance(programType);
eval.LoadContext = context;
eval.Stream = ms;
// do something here with the dynamically created class "eval"

а потім можна сказати

eval.LoadContext.Unload();
eval.Stream.Dispose();

Бонус, якщо ви введете це в інтерфейс IDisposable абстрактного класу, тоді ви можете просто використовувати, якщо хочете.

Примітка:
Це передбачає фіксований абстрактний клас у загальній збірці

public abstract class MyAbstractClass 
{

     public virtual void foo()
     {}
}

і динамічно генерований під час виконання клас (за допомогою Roslyn), посилаючись на абстрактний клас у загальній збірці, який реалізує, наприклад:

public class RsEval: MyAbstractClass 
{

     public override void foo()
     {}
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.