Хороший способ предварительно загрузить сборку .NET - PullRequest
20 голосов
/ 04 февраля 2011

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

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

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

Заранее спасибо.

Ответы [ 4 ]

19 голосов
/ 04 февраля 2011

Явная предварительная загрузка в вашем 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 голосов
/ 04 февраля 2011

Я верю, что Assembly.Load - это путь.

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

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

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

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

container.ResolveAll<Form>();

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

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

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

1 голос
/ 04 февраля 2011
var yourAppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Assembly.Load(Path.Combine(yourAppPath, "formAssembly.dll"));

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

0 голосов
/ 27 декабря 2017

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

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

Имя сборки можно найти в справочных свойствах Visual Studio:

assembly name in visual studio

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

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