【问题标题】:Use .NET assembly without locking dll file使用 .NET 程序集而不锁定 dll 文件
【发布时间】:2014-07-21 20:06:35
【问题描述】:

我有一个每天执行一次的 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);
    }
}

创建私有缓存但未锁定,原始文件已锁定。

【问题讨论】:

  • 您的 IShared 界面被加载到两个 appdomains 中。这将永久锁定在 DLL 上。将 Shared 类放在另一个类中。
  • 我之前转换为动态类型而不是接口,但它不起作用,所以这不是我的代码的唯一问题。

标签: c# .net .net-assembly appdomain appdomainsetup


【解决方案1】:

如果您有权修改使用程序集的所有代码,只需通过采用 byte[]Assembly.Load 重载加载它们就可以了。您将自己读取文件,并将其传递给该方法。我自己使用这种方法(但出于其他原因),它使我能够随时更新文件。

一个简单的方法(虽然有点奇怪)是重命名你的文件(从 .dll 到别的东西,所以它们找不到)然后订阅 AppDomain.AssemblyResolve 事件,这将被调用当它们丢失时,您可以让您的代码手动加载程序集。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-16
    相关资源
    最近更新 更多