当前位置:  开发笔记 > 编程语言 > 正文

COM互操作是否尊重.NET AppDomain边界以进行程序集加载?

如何解决《COM互操作是否尊重.NETAppDomain边界以进行程序集加载?》经验,为你挑选了1个好方法。

这是核心问题:我有一个在单独的AppDomain中使用COM互操作的.NET应用程序.COM的东西似乎是将程序集加载回默认域,而不是从中调用COM内容的AppDomain.

我想知道的是:这是预期的行为,还是我做错了导致这些COM相关程序集被加载到错误的AppDomain中?请参阅以下情况的更详细说明......

该应用程序由3个程序集组成: - 主EXE,应用程序的入口点. - common.dll,只包含一个接口IController(采用IPlugin风格) - controller.dll,包含一个实现IController和MarshalByRefObject的Controller类.此类完成所有工作并使用COM interop与另一个应用程序进行交互.

主要EXE的相关部分如下所示:

AppDomain controller_domain = AppDomain.CreateDomain("Controller Domain");
IController c = (IController)controller_domain.CreateInstanceFromAndUnwrap("controller.dll", "MyNamespace.Controller");
result = c.Run();
AppDomain.Unload(controller_domain);

common.dll只包含以下两件事:

public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun}
public interface IController
{
    ControllerRunResult Run();
}

controller.dll包含这个类(也调用COM互操作的东西):

public class Controller: IController, MarshalByRefObject

首次运行应用程序时,Assembly.GetAssemblies()看起来像预期的那样,在两个AppDomain中都加载了common.dll,并且只将controller.dll加载到控制器域中.在调用c.Run()之后,我看到与COM互操作内容相关的程序集已加载到默认的AppDomain中,而不是在发生COM互操作的AppDomain中.

为什么会发生这种情况?

如果你有兴趣,这里有一些背景知识:

最初这是一个AppDomain应用程序.它与之接口的COM东西是一个服务器API,它在长时间使用时不稳定.当COM东西发生COMException(没有关于其原因的有用诊断信息)时,整个应用程序必须重新启动才能再次使用COM连接.只需重新连接到COM应用服务器,就会再次导致COM异常.为了解决这个问题,我试图将COM互操作内容移动到一个单独的AppDomain中,这样当神秘的COMExceptions出现时,我可以卸载发生它的AppDomain,创建一个新的并再次启动,所有这些都无需手动重启应用程序.无论如何,这就是理论......



1> Shaun Wilson..:

不幸的是,A COM组件在Process Space中加载,而不是在AppDomain的上下文中.因此,您需要手动拆除(释放和卸载)Native DLL(适用于COM和P/Invoke).简单地破坏appdomain对你没有好处,但是重新生成整个过程不需要重置COM状态(简单地重新创建COM对象也应该正常工作,这听起来像组件提供者代码中的错误,也许他们可以解决吗?)

参考

(TechNet)进程地址空间

(MSDN)应用程序域

(MSDN)边界:进程和AppDomains

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有