AppDomain 卷影复制不起作用(原始程序集已锁定)

发布于 2024-11-17 07:33:37 字数 1247 浏览 4 评论 0原文

这是我用来探测可用插件列表的一个小类:

internal static class PluginDirectoryLoader
{
    public static PluginInfo[] ListPlugins(string path)
    {
        var name = Path.GetFileName(path);
        var setup = new AppDomainSetup
        {
            ApplicationBase = path,
            ShadowCopyFiles = "true"
        };
        var appdomain = AppDomain.CreateDomain("PluginDirectoryLoader." + name, null, setup);
        var exts = (IServerExtensionDiscovery)appdomain.CreateInstanceAndUnwrap("ServerX.Common", "ServerX.Common.ServerExtensionDiscovery");
        PluginInfo[] plugins = null;
        try
        {
            plugins = exts.ListPlugins(); // <-- BREAK HERE
        }
        catch
        {
            // to do
        }
        finally
        {
            AppDomain.Unload(appdomain);
        }
        return plugins ?? new PluginInfo[0];
    }
}

path 参数指向包含要加载的插件程序集的子目录。这个想法是使用启用了卷影复制的单独 AppDomain 来加载它们。

在这种情况下,卷影复制并不是真正必要的,因为 AppDomain 很快就被卸载了,但是当我实际在我打算编写的下一个代码块中加载插件时,我想使用卷影复制因此二进制文件可以即时更新。我在此类中启用了卷影复制作为测试,以确保我做得正确。

显然我做得不对,因为当我在代码示例中的注释行(即 plugins = exts.ListPlugins())上中断调试器时,原始插件程序集被应用程序锁定!

既然我指定 AppDomain 加载的程序集应该进行卷影复制,为什么它们被应用程序锁定?

Here's a small class I'm using to probe for a list of available plugins:

internal static class PluginDirectoryLoader
{
    public static PluginInfo[] ListPlugins(string path)
    {
        var name = Path.GetFileName(path);
        var setup = new AppDomainSetup
        {
            ApplicationBase = path,
            ShadowCopyFiles = "true"
        };
        var appdomain = AppDomain.CreateDomain("PluginDirectoryLoader." + name, null, setup);
        var exts = (IServerExtensionDiscovery)appdomain.CreateInstanceAndUnwrap("ServerX.Common", "ServerX.Common.ServerExtensionDiscovery");
        PluginInfo[] plugins = null;
        try
        {
            plugins = exts.ListPlugins(); // <-- BREAK HERE
        }
        catch
        {
            // to do
        }
        finally
        {
            AppDomain.Unload(appdomain);
        }
        return plugins ?? new PluginInfo[0];
    }
}

The path parameter points to a subdirectory containing the plugin assemblies to load. The idea is to load them using a separate AppDomain with shadow copying enabled.

In this case, shadow copying isn't really necessary seeing as the AppDomain is unloaded quickly, but when I actually load the plugins in the next block of code I intend to write, I want to use shadow copying so the binaries can be updated on the fly. I have enabled shadow copying in this class as a test to make sure I'm doing it right.

Apparently I'm not doing it right because when I break in the debugger on the commented line in the code sample (i.e. plugins = exts.ListPlugins()), the original plugin assemblies are locked by the application!

Seeing as I'm specifying that assemblies loaded by the AppDomain should be shadow copied, why are they being locked by the application?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江城子 2024-11-24 07:33:37

我想通了。我在 AppDomainSetup 中错过了一个属性。该属性是ShadowCopyDirectories

var setup = new AppDomainSetup
{
    ApplicationBase = path,
    ShadowCopyFiles = "true",
    ShadowCopyDirectories = path
};

当打破我的问题中提到的行时,即使不卸载 AppDomain,我现在也可以删除插件程序集。

I figured it out. There was one property I missed in AppDomainSetup. The property was ShadowCopyDirectories.

var setup = new AppDomainSetup
{
    ApplicationBase = path,
    ShadowCopyFiles = "true",
    ShadowCopyDirectories = path
};

When breaking on the line mentioned in my question, I can now delete the plugin assemblies even without unloading the AppDomain.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文