来自 COM 经验的八个教训
2006-07-22 22:53:22 来源:WEB开发网核心提示: 问题在于,太多的 COM 开发人员相信 ThreadingModel=Apartment 能够使他们免于编写线程安全的代码,来自 COM 经验的八个教训(6),事实并非如此 — 至少不完全如此,ThreadingModel=Apartment 并不意味着对象必须是完全线程安全的
问题在于,太多的 COM 开发人员相信 ThreadingModel=Apartment 能够使他们免于编写线程安全的代码。事实并非如此 — 至少不完全如此。ThreadingModel=Apartment 并不意味着对象必须是完全线程安全的,它代表的是一个对 COM 的承诺,即访问两个或更多对象实例共享的数据(或此对象和其他对象的实例共享的数据)时是以线程安全的方式进行的。而提供该线程安全性的任务应该由您,即对象实现者来负责。共享数据的类型和大小多种多样,但大多是以全局变量、C++ 类中的静态成员变量和函数中声明的静态变量的形式出现。即使是以下这样无害的语句也会在 STA 中出问题:
static int nCallCount = 0;
nCallCount++;
因为这个对象的所有实例都将共享一个 nCallCount 实例,编写这些语句的正确方式如下:
static int nCallCount = 0;
InterlockIncrement (&nCallCount);
注意:您可以使用临界区、互锁函数或您希望的任何方式,但不要忘了访问基于 STA 的对象共享的数据时要进行同步化!
谨慎启动用户
这里还有一个问题让许多 COM 开发人员都吃过苦头。去年春天,有一家公司向我紧急呼救,他们的开发人员使用 COM 构建了一个分布式应用程序,其中客户端进程运行在与远程服务器的 Singleton 对象相连接的网络工作站上。在测试过程中,他们遇到了一些非常奇怪的行为。在一种测试场景中,客户端对 CoCreateInstanceEx 的调用可使它们与 Singleton 对象正常连接。而在另一个场景中,对 CoCreateInstanceEx 的相同调用产生了多个对象实例和多个服务器进程,使客户端无法与同一个对象 实例连接,从而实际影响了应用程序。在这两个场景中,硬件和软件是完全相同的。
更多精彩
赞助商链接