gpt4 book ai didi

c# - 从 COM 库转换到接口(interface)在 IIS 中的第 16 个托管线程上失败(InvalidCastException,WinRT 起源错误 0x80040155)

转载 作者:行者123 更新时间:2023-11-30 22:57:29 24 4
gpt4 key购买 nike

我发布这篇文章主要是为了遇到这个奇怪问题的其他人,如果有人能阐明为什么 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 中实现的,类型库用于创建 Interop DLL 并重新加载。

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

myFoo as IBar

(IBar) myFoo

没有任何问题。直到……

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

    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

类型转换突然返回空值。但是对象本身仍然有效并且可以被询问,只是不再被强制转换。

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

最佳答案

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

我是怎么到那里的?

鉴于该错误代码,我检查了注册表,正如我从痛苦的经历中了解到的那样,C# 或 OLE 喜欢在注册表中定义接口(interface),这样它就知道该做什么,而不是使用 Interops/TLB 的细节。

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

捕获救命稻草我想,如果它只需要存在注册表项怎么办?因此,我一个一个地添加属性,直到正确的一个将注册表设置插入,将 oleautomation 添加到 IBar 接口(interface)属性就可以了。它突然修复了它,不再有转换失败。

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

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

关于c# - 从 COM 库转换到接口(interface)在 IIS 中的第 16 个托管线程上失败(InvalidCastException,WinRT 起源错误 0x80040155),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53617518/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com