Используйте сборку.NET без блокировки файла DLL
У меня есть служба Windows, которая выполняется один раз в день. Это всего лишь 10 минут действия.
Я создаю файлы сервиса в папке bin сайта, потому что сервис использует dll сайта.
К сожалению, я заметил, что когда я установил модуль веб-сайта (модуль dotnetnuke.zip установщиком веб-сайта), я получил ошибку, что файл заблокирован другим процессом.
Отключение службы перед установкой каждого модуля очень проблематично, поэтому я хочу, чтобы моя служба не блокировала используемые в ней библиотеки DLL.
Я читал об опциях AppDomain и ShadowCopyFiles, но не могу заставить их работать на меня.
Это пример того, как я использую ShadowCopyFiles:
class Program
{
static string GenerateRandomName()
{
//maybe name must be unique?!
var random = new Random();
return "a" + random.Next().ToString() + "b" + random.Next();
}
static int RandomNumber()
{
var info = ConfigureAppDomainSettings();
var domain = AppDomain.CreateDomain(GenerateRandomName(), null, info);
var assembly = domain.Load("SharedLibrary");
var shared = (SharedLibrary.IShared)assembly.CreateInstance("SharedLibrary.Shared");
int retVal = shared.RandomNumber();
AppDomain.Unload(domain);
domain = null;
assembly = null;
shared = null;
info = null;
Console.WriteLine("before cleanning");
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForFullGCComplete();
GC.Collect();
Console.WriteLine("after cleanning");
return retVal;
}
static AppDomainSetup ConfigureAppDomainSettings()
{
AppDomainSetup domainSettings = AppDomain.CurrentDomain.SetupInformation;
domainSettings.ShadowCopyFiles = "true";
domainSettings.CachePath = @"C:\inetpub\wwwroot\eshop\DesktopModules\Rossnet_EShop\SharedAssemblyTest\PrivateCache";
return domainSettings;
}
static void Main(string[] args)
{
Console.WriteLine(RandomNumber());
Console.ReadKey();
}
}
Код примера сборки:
public interface IShared
{
int RandomNumber();
}
[Serializable]
public class Shared : IShared
{
public int RandomNumber()
{
var random = new Random();
return random.Next(20);
}
}
Закрытый кеш создается и не блокируется, а исходный файл блокируется. <- сейчас это абсурдно для меня.
1 ответ
Если у вас есть доступ для изменения всего кода, который использует сборки, просто загрузите их с помощью перегрузки Assembly.Load, которая принимает byte[]
должен сделать свое дело. Вы сами прочитаете файл и передадите его этому методу. Я сам использую этот подход (хотя и по другим причинам), и он дает мне возможность обновлять файлы в любое время.
Способ сделать это легко (хотя и немного странно) - переименовать ваши файлы (из.dll во что-то другое, чтобы их нельзя было найти), а затем подписаться на событие AppDomain.AssemblyResolve, которое будет вызываться, когда они отсутствует, в этот момент вы можете иметь свой код, который загружает сборки вручную.