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



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

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

换句话说:

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

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

在做出任何修复决定之前,我正在尝试评估所有可能的解决方案。因此,我正试图找出:

1) 有没有一种方法可以从一开始就防止RPC回调线程被使用?在我的测试中,如果我从非托管STA线程对对象进行调用,那么这些调用似乎来自调用线程本身。当调用来自需要使用RPC回调线程的.Net时,有什么不同?有什么方法可以防止RPC回调被使用吗?(使用MTA调用线程除外)

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

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

因此,您不能使用互斥实现锁定,因为它具有线程亲和性。信号灯是个不错的选择。

最新更新