我有一个每天执行一次的Windows服务。这只是10分钟的行动。
我在网站的bin文件夹中构建服务的文件,因为该服务使用网站dll。
不幸的是我注意到当我安装网站模块(网站安装程序的dotnetnuke .zip模块)时,我收到一个错误,该文件被antoher进程锁定。
在安装每个模块之前禁用该服务是非常有问题的,所以我想让我的服务不能锁定其中使用的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);
}
}
创建私有缓存但未锁定,原始文件被锁定。 < - 现在这对我来说很荒谬。
答案 0 :(得分:9)
如果您有权修改使用程序集的所有代码,只需通过需要byte[]
的{{3}}重载加载它们就可以了。您将自己阅读该文件,并将其传递给该方法。我自己使用这种方法(但出于其他原因),它使我能够随时更新文件。
轻松完成此操作(尽管有点奇怪)的方法是重命名文件(从.dll到其他内容,因此无法找到它们),然后订阅Assembly.Load 事件,这将是当它们丢失时被调用,此时你可以让你的代码手动加载程序集。