Bezdepbonusu7Программирование: статьи и ответы

Вопрос

ASP.NET забывает DLL в каталоге bin

Автор вопроса: Timothy StrimpleОтветов: 5

У нас есть система плагинов в службе WCF, которая проверяет библиотеки, помещенные в папку bin, на наличие определенных атрибутов уровня сборки и загружает их. Это позволяет настраивать определенные сервисные вызовы в зависимости от того, какой клиент делает вызов. Это отлично работает большую часть времени. Однако иногда кажется, что dll теряется, что заставляет службу возвращаться к реализации по умолчанию для каждого клиента. До сих пор решение заключалось в том, чтобы просто переместить файл dll из папки bin и обратно. Это заставляет asp.net забрать файл, и настройки снова начинают работать.

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

Изменить: проблема сформулирована более четко

Наши сервисы используют фабрику сервисов для предоставления пользовательских реализаций в зависимости от того, какой клиент вызывает код. Если пользовательской реализации нет, мы выдаем реализацию по умолчанию. Мы используем GetAssemblies для проверки сборок, которые украшены атрибутом, определяющим их как пользовательскую реализацию и связывающим их с клиентом. Проблема в том, что GetAssemblies перестает возвращать пользовательскую сборку клиента, даже если библиотека остается в папке bin. Перемещение dll из корзины и обратно в нее решит проблему примерно на неделю, пока она не повторится.

  • что больше не использует пользовательскую реализацию? Ваш код? Вы имеете в виду, что вызов GetAssemblies() не возвращает сборки, которые, по вашему мнению, он должен возвращать? Проблема не очень четко описана. Cheeso 23.03.2010
  • Наши сервисы используют фабрику сервисов для предоставления пользовательских реализаций в зависимости от того, какой клиент вызывает код. Если пользовательской реализации нет, мы выдаем реализацию по умолчанию. Мы используем GetAssemblies для проверки сборок, украшенных атрибутом, определяющим их как пользовательскую реализацию и связывающим их с клиентом. Проблема в том, что GetAssemblies перестает возвращать пользовательскую сборку клиента, даже если библиотека остается в папке bin. Перемещение dll из корзины и обратно в нее решит проблему примерно на неделю, пока она не повторится. Timothy Strimple 24.03.2010
  • вы получаете сообщение об ошибке или предупреждение в журналах событий? Кроме того, какое-либо антивирусное программное обеспечение работает на этом устройстве? SoftwareGeek 25.03.2010

iis

Ответы

Ответ 1 · рейтинг 4 · Fadrian Sudaman

Проблема, с которой вы столкнулись, должна быть связана с автоматической перезапуском домена приложения. Очевидно, перезапуск домена приложения ведет себя иначе, чем настоящий перезапуск. При повторном использовании он будет загружать только те dll, которые явно указаны и загружаются по мере необходимости. См. эту ссылку http://www.chrisvandesteeg.nl/2006/06/15/appdomain-recycle-other-from-real-restart/

Тот факт, что GetAssemblies вернет вам только ту сборку, которая в данный момент загружена в домен приложения, может объяснить аномалию, которую вы получаете с вашей программой. Чтобы быть в безопасности, если вы имеете дело с библиотекой типов плагинов, вы всегда должны сканировать файлы плагинов (dll) и загружать их явно с помощью Assembly.LoadFrom. Другой альтернативой является размещение ваших служб WCF на внешнем пользовательском узле, таком как оконная служба, чтобы срок службы узла не подпадал под действие политики повторного использования IIS.

Прочитайте это для получения дополнительной информации об утилизации домена приложения http://blogs.msdn.com/tess/archive/2006/08/02/asp-net-case-study-lost-session-variables-and-appdomain.-recycles.aspx

Ответ 2 · Bryan

Как загружаете сборки? Следующий вопрос... почему? Сборки в каталоге bin должны автоматически загружаться и быть доступными для приложений ASP.NET, которые на них ссылаются. Возможно, вы получаете здесь какой-то конфликт... т. е. доступ запрещен, потому что какой-то другой поток/процесс имеет открытый дескриптор сборки. Извините, что так расплывчато, но это единственное, что сразу приходит на ум. Вы можете потенциально использовать FileMon или аналогичный инструмент, чтобы проверить это.

Кроме того... что именно вы подразумеваете под "потерять" DLL? Вы вызываете какой-то конкретный метод, чтобы найти его, и он терпит неудачу? В чем ошибка? Вы проверили средство просмотра событий на наличие необработанных исключений?

Ответ 3 · Robert C. Barth

GetAssemblies возвращает только список уже загруженных сборок. Если вы не использовали тип из этой сборки, он еще не загружен. Вам нужно использовать Assembly.Load, чтобы загрузить нужную сборку с диска; сборки в папке /bin не загружаются автоматически в домен приложения.

Кроме того, вы можете использовать Managed Extensibility Framework (MEF), она была разработана специально для обработки функциональность, о которой вы говорите.

Ответ 4 · Raj Kaimal

... замена сборки в каталоге \bin приведет к новой пакетной компиляции этого каталога.

http://msdn.microsoft.com/en-us/library/5dws599a(VS.71).aspx

У вас есть код инициализации в Application_Start внутри global.aspx?

Ответ 5 · emalamisura

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы