2

我主要是为遇到这个奇怪问题的其他人发布这个,如果有人能解释为什么 IIS/Cassini 是一个魔鬼。

在大多数情况下,我们可以成功地将 ODL 中定义的 Dispatch 对象转换为

[ uuid(GUID_FOO) ]
dispinterface IFooDisp
{
    ... properties & methods.
};
[ uuid(GUID_FOO_COCLASS),noncreatable ]
coclass FooDisp
{
    [default] dispinterface IFooDisp;
};

到如下界面

[ uuid(GUID_BAR) ]
interface IBar : IUnknown
{
    ... some methods
}

以上都是在注册的 C++ OLE/COM 自动化 DLL 中实现的,并且类型库用于创建一个互操作 DLL 并且它是 regasm'd。

所以在 C# 中我们可以成功地反复调用

myFoo as IBar

(IBar) myFoo

没有任何麻烦。直到....

我们发现,如果我们打开一个网页,转到服务器上的一个 URL,关闭浏览器并重复 16 次(Cassini 或 IIS),当创建第 16 个托管线程时,突然转换失败,并出现以下基本异常:

    Exception Thrown at 0x75151812 (KernelBase.dll) in My.exe: 
WinRT originate error - 0x80040155 : 'Failed to find proxy registration for IID: {GUID_BAR}.' 

测试时

(myFoo as IBar)!=null

演员突然返回 null 。但是对象本身仍然有效并且可以被询问,只是不再投射。

为什么它在第 16 个线程上失败,并且事先工作正常?Ps 一切都设置为 STA。我该如何解决?

4

1 回答 1

2

我可以告诉你如何修复它,添加oleautomation到 IBar 属性。但我不确定为什么有必要。

我是怎么到那里的?

鉴于该错误代码,我检查了注册表,从痛苦的经验中得知,C# 或 OLE 喜欢在注册表中定义接口,因此它知道该做什么,而不是使用 Interops/TLB 的详细信息。

在搜索时,我发现注册表没有包含 GUID_BAR 作为键,因此没有代理/存根详细信息,就像所有其他接口一样。

抓住稻草我想,如果它只需要存在注册表项怎么办?所以我一一添加属性,直到正确的将注册表设置推入,添加oleautomation到 IBar 界面属性就可以了。它突然修复它,没有更多的失败施法。

但我不知道为什么 C# 在第 16 个托管线程之前都可以正常工作。每个线程都有自己的一组对象(没有跨线程调用,以及托管到 COM 线程的 1:1 映射)。在尝试通过自动化测试重现这一点时,简单地创建数百个线程并进行类似的工作不会导致同样的失败。IIS 一定有什么特别之处。

也许元数据被清除并重新收集?有人可以解释更多吗?

于 2018-12-04T16:31:54.790 回答