在单线程单元模型中,对方法的任何调用都是同步的吗?

In Single Thread Apartment model, is any call to a method is synchronised?

我的疑惑是,在STA中对同一个接口中的不同方法的调用是否要排队?或对同一接口中同一方法的调用排队?

首先是过度简化:

单线程单元 (STA) 是用于同步 COM 对象的构造,而不是方法。只要大家遵守规则,就可以保证对象一次只能被一个客户端访问,即一次只能调用一个方法。当您处于不同调用的中间时,同一对象中的任何方法(当然我的意思是 'same instance',而不是 'of the same class')都不会被不同的线程随机调用。

如果您需要提供更细粒度的同步,例如,只需要同步一个方法体,那么公寓机制不适合您。最灵活的方法是使您的对象成为自由线程,并在需要时手动编写您自己的同步代码。这当然是更多的工作。

现在,我需要说得更准确一些,因为我们都只是手把手地挥舞着很多非常重要的细节:

单线程单元的真正目标是为对象提供线程亲和性。 COM 对象的代码只能运行 创建对象的线程,不能有其他人。如果不同的线程需要与您的对象对话,它们必须等到拥有您的对象的线程可用。事实上,在很多情况下,这意味着方法调用是排队的,这是一个自然的副作用。

"很多场景?"

是的。因为公寓不会阻止重入。您的方法 A() 可以在同一对象上调用另一个方法 B()。 B() 可以回调 A() 。或者 A() 可以调用 object2->MethodX(),它本身会在您仍在执行 A() 的过程中调用您自己的方法 D()。或者 A() 可以触发事件(请参阅连接点),事件处理程序可以在您的对象上调用不同的方法 E()。因此,将 COM 单元称为对象的同步机制是一种简化,如果您不考虑细节,可能会给您带来麻烦。

当然,互斥量和其他同步原语也是线程绑定的,因此它们具有相同的重入警告。但是通过使用模糊的语言,它可能会让您认为公寓会做一些他们不会做的事情。认为在 STA 对象中一次只能激活一个方法是一种危险的思维模型。

线程亲和性是 Single Threaded Apartments 的一个关键目标,因为 COM 被设计为 OLE 的现代基础(您可以在其中将电子表格的一系列单元格拖动到 Microsoft Word 文档中),在多线程世界。 OLE 对象在很大程度上依赖于图形系统资源来绘制它们的图像,而这些资源是线程仿射的。