【发布时间】:2010-09-19 12:50:02
【问题描述】:
这是核心问题:我有一个在单独的 AppDomain 中使用 COM interop 的 .NET 应用程序。 COM 东西似乎正在将程序集加载回默认域,而不是从中调用 COM 东西的 AppDomain。
我想知道的是:这是预期的行为,还是我做错了什么导致这些与 COM 相关的程序集被加载到错误的 AppDomain 中?请参阅下面的情况更详细的描述...
该应用程序由 3 个程序集组成: - 主 EXE,应用程序的入口点。 - common.dll,只包含一个接口 IController(IPlugin 风格) - controller.dll,包含一个实现 IController 和 MarshalByRefObject 的 Controller 类。此类完成所有工作并使用 COM 互操作与另一个应用程序进行交互。
主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() 看起来与预期一样,common.dll 加载到两个 AppDomain 中,而 controller.dll 仅加载到控制器域中。然而,在调用 c.Run() 之后,我看到与 COM 互操作相关的程序集已加载到默认 AppDomain 中,而不是在发生 COM 互操作的 AppDomain 中。
为什么会发生这种情况?
如果你有兴趣,这里有一点背景:
最初这是一个 1 AppDomain 应用程序。它与之交互的 COM 东西是一个服务器 API,长期使用并不稳定。当 COM 发生 COMException(没有关于其原因的有用诊断信息)时,必须重新启动整个应用程序,然后 COM 连接才能再次工作。简单地重新连接到 COM 应用程序服务器会再次立即导致 COM 异常。为了解决这个问题,我尝试将 COM 互操作的东西移动到一个单独的 AppDomain 中,这样当神秘的 COMExceptions 发生时,我可以卸载它发生的 AppDomain,创建一个新的并重新开始,而无需手动重新启动应用程序.无论如何,这就是理论......
【问题讨论】:
-
fyi,如果其他人看一下这个 - 这是 HP Quality Center API DLL 给我这个问题。我通过让应用自行重启来解决这个问题,但我仍然对为什么会发生这种情况很感兴趣。
标签: c# com interop com-interop appdomain