【发布时间】:2014-08-10 06:28:50
【问题描述】:
由于某种原因,当它们应该是单例时,正在创建 2 个对象。
我有一个类 Bridge,其目的是从一个应用程序到另一个应用程序进行通信。第一个应用 App1 通过 COM 创建网桥并立即调用网桥的初始化方法:
bool IBridge.Initialize(ref App1 theApp)
{
if (theApp != null)
{
this.refToApp = theApp;
log("Got bridge from App1");
//spin up App2
Process.Start([path to App2]);
}
else
{
log("theApp was null");
}
return true;
}
Bridge 类使用单例模式,但有一个公共默认构造函数,以便 COM 可以正常使用它,但此类的用户必须通过仅使用实例属性访问它来尊重它是单例的事实。
[ComVisibleAttribute(true)]
[ProgId("[id that App1 uses to instantiate class]")]
public class Bridge : IBridge
{
private static readonly _instance;
public static COMBridge Instance
{
get
{
if(_instance == null){
_instance = new Bridge();
}
return _instance
}
}
public Bridge()
{
log("Called default constructor");
if (_instance == null)
{
_instance = this;
}
}
...
但是,当 App2 启动时,它会调用 Instance 的 getter 并再次调用构造函数。这很麻烦,因为桥接器是一个通信组件,我需要这两个应用程序使用桥接器相互通信。
有什么建议吗?
【问题讨论】:
-
假设两个线程/进程同时执行
if(_instance == null),会发生什么? -
com 对象是否作为程序集 (.dll) 实现?如果是这样,是什么让您认为这两个进程都在寻找 com 对象的同一个实例?
-
@L.B 我认为这不是线程问题,因为调用相距甚远。就像我记录对构造函数的调用并且它们彼此分开一秒钟被调用,所以我不认为这是这里的问题(我确实认识到这是糟糕的代码,但我只需要它开始工作!)
-
@user957902 我认为这是我的问题。奇怪的是,以前,App2 是用 VB 编写的,它会调用一个返回相同对象的
CreateObject(progId)方法。现在我正在用 C# 编写 App2,它的工作方式似乎有所不同 -
一旦你使用公共构造函数创建你的类 [ComVisible(true)] 然后游戏就开始了,客户端代码总是可以创建一个新对象。如果 _instance 不为空,您只能通过在构造函数中抛出异常来强制执行合同。这不太可能使客户端程序员的螺旋桨旋转。一个更有用的方案是不让你的类[ComVisible],只有接口。并提供 another [ComVisible] 类,该类具有返回唯一接口引用的工厂方法。您需要考虑一生。