Подтвердить что ты не робот

Хороший способ предварительной сборки .NET сборки

В моем приложении мне нужно показать форму при щелчке мыши. Проблема в том, что форма находится в другой сборке, и из-за ленивой загрузки сборки, вероятно, сборка еще не загружена при нажатии кнопки мыши. Так что у меня есть очень заметная пауза, прежде чем форма наконец появится.

Я смог придумать немое исправление, вызвав new FormFromAnotherAssembly() в моем методе инициализации. Это, конечно, позаботилось о вещах, и паузы больше нет, но это очень уродливо. Единственное, что мне нравится в этом решении, это то, что мне не нужно возиться с путями и именами сборки, которые мне нужно делать, если я хочу использовать что-то вроде Assembly.Load.

Итак, какое хорошее, надежное решение для выбора, если я хочу убедиться, что сборка загружена, прежде чем я на самом деле нуждаюсь в ней?

Спасибо заранее.

4b9b3361

Ответ 1

Явная предварительная загрузка в вашем init, вероятно, по-прежнему является вашим лучшим вариантом.

a typeof(SomeTypeFromAnotherAssembly) должно быть достаточно - наряду с непрозрачным методом, который нельзя оптимизировать; возможно:

GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly));

Это позволяет избежать new. Обратите внимание, что это будет загружено, но не JITted и т.д.

Если вы захотите, вы можете сделать это по потоку BG:

private static void LoadSomeStuff(object state) {
    GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly));
}
...
ThreadPool.QueueUserWorkItem(LoadSomeStuff);

Ответ 2

Я считаю, что Assembly.Load - это путь.

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

Или другой и лучший вариант: почему вы не используете для этого инверсию управления?

Вы можете использовать Castle Windsor для этого. Скажем, у вас есть 4 формы для загрузки во время выполнения, поэтому вы можете создать 4 компонента класса Form, которые их реализация представляет собой 4 формы для загрузки в течение жизненного цикла вашей программы.

Как предварительно загрузить этот подход? Вы просто решаете все зависимости/компоненты, относящиеся к типу формы, и вы получили его:

container.ResolveAll<Form>();

Позже вы получите конкретную форму:

container.Resolve<Form>("CustomersForm"); // Just an example

Если вы не знаете инверсию управления, закомментируйте, и я помогу вам, не проблема!:)

Ответ 3

var yourAppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Assembly.Load(Path.Combine(yourAppPath, "formAssembly.dll"));

Будет ли это делать?

Ответ 4

Я думаю, что самый простой способ - просто использовать имя сборки в Assembly.Load():

System.Reflection.Assembly.Load("ICSharpCode.AvalonEdit");

Вы можете найти имя сборки под ссылочными свойствами в Visual studio:

имя сборки в visual studio

Таким образом, вы можете избежать ввода путей к файлам DLL и т.д. Я использую это, чтобы ускорить загрузку диалогового окна, использующего эту DLL. Как только основное окно программы полностью загружено, он запускает фоновый поток, который просто вызывает Assembly.Load(). Когда пользователь открывает этот диалог, небольшое отставание от загрузки этой DLL отсутствует.