0

我正在处理与非托管 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 回调线程?

4

1 回答 1

1

这是为自由线程服务器设计的。COM 相信你的话,并允许存根使用任意 RPC 线程。您不能对线程身份做出任何假设,RPC 线程是从池中挑选出来并被回收的。不幸的是,当调用被排序时,它通常会选择同一个,所以它看起来一开始就可以正常工作。但是一旦进行了多个并发服务器调用,麻烦就开始了。没有选择使其具有选择性,自由线程服务器承诺不在乎。这在实践中也不能很好地工作,它要么会可怕地扩展,要么会导致僵局。

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

于 2013-07-15T16:27:10.347 回答