0

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

4

1 回答 1

2

首先是过度简化:

单线程单元 (STA) 是用于同步 COM 对象的构造,而不是方法。只要每个人都按规则行事,就可以保证对象一次只能被一个客户端访问,即一次只能调用一个方法。当您处于不同调用的中间时,同一对象中的任何方法(当然我的意思是“相同的实例”,而不是“同一类的”)都不会被不同的线程随机调用。

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

现在,我需要更加精确,因为我们都只是在挥手很多非常重要的细节:

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

很多场景?

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

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

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

于 2018-07-20T00:48:44.163 回答