Я хотел бы обновить dll для серверного процесса, не останавливая службу. Как мне это сделать? Немного похоже на то, как asp.net автоматически собирает новые dll, помещенные в папку bin.
Обновление dll без остановки службы
Ответ 1
В Asp.Net используется метод теневая копия
Если вы скопируете обновленную dll в поддиректорию bin bin, среда выполнения ASP.NET распознает, что есть новый код для выполнения. Поскольку ASP.NET не может заменить dll в существующий AppDomain, он запускает новый AppDomain. Старый домен приложения "сток остановлен", то есть существующие запросы разрешены для завершения выполнения, и как только все они будут завершены, AppDomain может выгрузить. Новый AppDomain начинается с нового кода и начинает принимать все новые запросы.
Обычно, когда DLL загружается в процесс, процесс блокирует DLL, и вы не можете перезаписать файл на диске. Тем не менее, AppDomains имеет функцию, известную как Shadow Copy, которая позволяет сборкам оставаться разблокированными и сменными на диске.
Время выполнения инициализирует ASP.NET с включенным Shadow Copy для каталога bin. AppDomain скопирует любую необходимую DLL из каталога bin во временное место перед блокировкой и загрузкой dll в память. Shadow Copy позволяет перезаписывать любую DLL в каталоге bin во время обновления без отключения веб-приложения.
Ответ 2
В дополнение к ответу Гульзара:
Если ваша служба просто ссылается на DLL, вам нужно будет немного заново спроектировать службу, чтобы использовать возможности AppDomains и ShadowCopy, чтобы воспользоваться этой возможностью.
Мы делаем что-то вроде этого, когда служба - это просто процесс оболочки/хоста. Вся функциональность загружается в отдельные домены приложений в случае необходимости.
Ответ 3
Когда процесс загрузил dll, его невозможно изменить.
IIS не сохраняет DLL, загруженную в память, когда она не используется (затронутое свойством Cache), и я предполагаю, что в ASP.NET. Если вы будете следовать той же стратегии, вы также можете обновить свои DLL.
Однако, если ваши DLL используются, вы должны иметь способ сообщить серверному процессу разгрузить все ваши DLL.
Для этого серверный процесс должен загружать все DLLS, используя вызовы LoadLibrary, чтобы он мог выгрузить их, когда он получает сообщение, требующее его сделать.
Общение с процессом сервера может быть выполнено путем создания глобально доступного именованного события, доступ к которому может получить новая программа, и используется для оповещения о запущенном процессе обновления. (Вы также можете подумать о других вариантах этого).