Сбой приведения к интерфейсу из библиотеки COM в 16-м управляемом потоке в IIS (InvalidCastException, ошибка WinRT 0x80040155) - PullRequest
0 голосов
/ 04 декабря 2018

Я публикую это в основном для всех, кто сталкивается с этой странной проблемой, и если кто-то может пролить свет на то, почему IIS / Cassini является дьяволом.

По большей части, мы можем успешно разыгратьобъект Dispatch, определенный в ODL как

[ 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 и она 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

Приведение внезапно возвращает ноль.Но сам объект все еще действителен и может быть опрошен, но больше не приведен.

Почему он не работает в 16-м потоке и прекрасно работает заранее?Ps все настроено на STA.Как мне это исправить?

1 Ответ

0 голосов
/ 04 декабря 2018

Я могу рассказать вам, как это исправить, добавив oleautomation к атрибутам IBar.Но я не уверен, зачем это нужно.

Как я туда попал?

Учитывая этот код ошибки, я проверил реестр, как я знаю из мучительного опыта, что C # или OLE любит иметь интерфейсы, определенные в реестре, поэтому он знает, что делать, а не использует детали Interops / TLB.

При поиске я обнаружил, что реестр не содержит GUID_BAR в качестве ключа и, следовательно, не содержит никаких сведений о прокси / заглушке, как и все другие интерфейсы.если ему просто нужен ключ реестра для существования?Поэтому я добавлял атрибуты один за другим, пока правый не выдвинул настройки реестра, добавив oleautomation к атрибуту интерфейса IBar.Он внезапно исправил это, больше не было ошибок приведения.

Но я не знаю, почему C # работал нормально до 16-го управляемого потока.Каждый поток имеет свой собственный набор объектов (нет вызовов между потоками и отображение 1: 1 управляемых потоков COM).При попытке воспроизвести это с помощью автоматического теста простое создание сотен потоков и выполнение аналогичной работы не приводит к одному и тому же отказу.Это должно быть что-то особенное в IIS.

Может быть, метаданные очищаются и повторно собираются?Может кто-нибудь объяснить больше?

...