Com 是否可以指定使用RPC回调线程?

Com 是否可以指定使用RPC回调线程?,com,com-interop,Com,Com Interop,我正在处理一个与非托管MTA COM对象相关的错误。该对象具有Lock和Unlock方法,并使用一个互斥锁,该互斥锁要求调用Lock的线程调用Unlock 问题在于,当从托管STA线程(使用COM互操作)调用Lock和Unlock时,调用会进入RPC回调线程上的COM对象,但用于两个调用的回调线程并不总是相同的。如果不相同,解锁调用将失败,因为它无法解锁互斥锁 换言之: 托管STA线程1->RPC回调(线程11)->锁定 托管STA线程1->RPC回调(线程12)->解锁->错误 我正在尝试评估

我正在处理一个与非托管MTA COM对象相关的错误。该对象具有Lock和Unlock方法,并使用一个互斥锁,该互斥锁要求调用Lock的线程调用Unlock

问题在于,当从托管STA线程(使用COM互操作)调用Lock和Unlock时,调用会进入RPC回调线程上的COM对象,但用于两个调用的回调线程并不总是相同的。如果不相同,解锁调用将失败,因为它无法解锁互斥锁

换言之:

托管STA线程1->RPC回调(线程11)->锁定

托管STA线程1->RPC回调(线程12)->解锁->错误

我正在尝试评估所有可能的解决方案,然后再决定修复方案。因此,我试图找出:


1) 有没有一种方法可以首先防止使用RPC回调线程?在我的测试中,如果我从非托管STA线程对对象进行调用,则调用似乎来自调用线程本身。当调用来自需要使用RPC回调线程的.Net时,有什么不同?是否有任何方法可以防止使用RPC回调?(使用MTA调用线程除外)


2) 如果没有,是否有办法强制从同一托管STA线程使用一致的RPC回调线程?

这是为自由线程服务器设计的。COM相信您的话,允许存根使用任意RPC线程。您不能对线程标识进行任何假设,RPC线程是从池中拾取并回收的。不幸的是,当调用被排序时,它通常会选择相同的一个,所以它看起来一开始工作正常。但一旦发生多个并发服务器调用,问题就开始了。没有选择使其具有选择性,自由线程服务器承诺不会在意。这在实践中也不可能很好地发挥作用,它要么规模巨大,要么导致僵局


因此,不能使用互斥锁来实现锁定,因为它具有线程亲和力。信号量是一个很好的选择。

“在我的测试中,如果我从非托管STA线程调用对象,调用似乎是在调用线程本身上进行的。”只有在单元之间传递了原始接口指针而没有进行适当的封送时,才会出现这种情况,这违反了COM线程规则。