我的疑问是,在STA中,是否对在同一接口中的不同方法的调用进行排队?还是在同一接口中调用同一方法?
答案 0 :(得分:2)
首先过度简化:
单线程单元(STA)是用于同步COM对象而不是方法的结构。只要每个人都遵守规则,就可以保证一次只能由一个客户端访问该对象,即一次只能调用一种方法。当您处于不同的调用中间时,同一对象中的任何方法(当然,我的意思是“相同的实例”,而不是“相同的类”)不会被不同的线程随机调用。
例如,如果您需要提供更精细的同步,则只需要同步一个方法主体,那么套间不是您合适的机制。最灵活的方法是使对象成为自由线程,并在需要时手动编写自己的同步代码。当然,这是更多的工作。
现在,我需要更加精确,因为我们俩都在挥舞着很多非常重要的细节:
单线程公寓的真正目标是为对象提供线程亲和力。 COM对象的代码只能在创建该对象的线程中运行 ,而没有其他人可以运行。如果其他线程需要与您的对象对话,则它们必须等待直到拥有您对象的线程可用为止。在许多情况下,这意味着方法调用已排队,这一事实是其自然的副作用。
“ 有很多情况吗?”
是的。因为公寓不能阻止人们进入。您的方法A()可以在同一对象上调用另一个方法B()。 B()可以回叫A()。或者,A()可以调用object2-> MethodX(),而您仍在执行A()的过程中,该方法本身会调用您自己的方法D()。或A()可以触发一个事件(请参阅连接点),并且事件处理程序可以在您的对象上调用另一个方法E()。因此,将COM套间作为对象的同步机制是一种简化,如果您不考虑细节,可能会惹上麻烦。
当然,互斥体和其他同步原语也是线程绑定的,因此它们具有相同的可重入警告。但是,通过使用模糊的语言,您可能会觉得公寓在做一些自己做不到的事情。认为在STA对象中一次只能激活一种方法是一种危险的心理模型。
线程亲和性是单线程公寓的一个主要目标,因为在多线程世界中,COM被设计为OLE(可以将电子表格的一系列单元格拖到Microsoft Word文档中的现代基础)。 。 OLE对象在很大程度上依赖于图形系统资源来绘制其图像,并且这些资源是线程仿射的。