.NET STA Com Объект от квартиры МТА - PullRequest
1 голос
/ 28 марта 2012

В данный момент я работаю над сайтом (MVC), который довольно активно использует ajax для запроса данных от медленно реагирующих асинхронных ресурсов.

У меня проблема, хотя, каждый запрос должен быть сначала авторизован, и часть этой авторизации должна получить текущее имя пользователя RSA, выполнив Server.CreateObject ("Rsacookieapi.RSACookie"). GetUserName (). Проблема в том, что этот конкретный com-объект не запускается в MTApartments, а только в STAparatments (они не предлагают никакого альтернативного компонента .net, поэтому мы должны его использовать), поэтому CreateObject завершается ошибкой.

Я обошел это благодаря многим исследованиям, создав собственный обработчик маршрута, который выполняет контекст контроллера в STA (эквивалентно выполнению ASPCOMPAT = TRUE для веб-форм), но это приводит к дальнейшей проблеме, я больше не могу создавать асинхронный методы контроллера, когда контекст контроллера выполняется из STA.

Поэтому я начал думать, что если бы я мог создать COM-объект в STA и каким-то образом создать для него делегат / маршал, чтобы к нему можно было получить доступ из MTA, тогда все было бы хорошо.

В качестве подтверждения концепции у меня была глобальная переменная myComObject, которую я заполнил, выполнив CreateObject из запроса STA (/StaController/Index).

Затем я попытался получить доступ к myComObject из запроса MTA (/MtaController/Index).

Хорошая новость в том, что это работает. Похоже, что клиент обрабатывает все сортировки для меня.

Итак, я начал писать некоторый код, который порождает новый поток в STA, но проблема в том, что я все еще обязан передавать HttpContext.Current.Server (HttpServerUtilityBase) в поток, который при вызове .CreateObject в любом случае он просто выполняет его на MTA объекта .Server.

Надеюсь, это имеет смысл? Для уточнения:

  1. Я не хочу, чтобы какой-либо из моих контроллеров или действий выполнялся на STA
  2. Я хочу создать объект на STA, а затем предоставить доступ к нему из всех других MTA

Я искренне надеюсь, что у кого-то есть предложение!

Привет

Karl

1 Ответ

3 голосов
/ 28 марта 2012

Вариант 1. Используйте Tlbimp для создания сборки.

Вы пытались использовать Tlbimp.exe для создания сборки для компонента и использовать это?Документация говорит, что это приводит к "плохой работе".Но это происходит из-за требуемой сортировки, которая аналогична той, что вы пытаетесь сделать здесь.

http://msdn.microsoft.com/en-us/library/zwk9h2kb.aspx

Атрибут AspCompat заставляет страницу выполняться вРежим STA.Среда выполнения выдает исключение, если тег совместимости опущен, а компонент STA указан на странице. Если вы преобразуете компонент STA в сборку с использованием Tlbimp.exe, среда выполнения не обнаружит, что компонент использует модель STA , и не выдаст исключение, но ваше приложение может пострадать из-за низкой производительности.

Вариант 2: Ложь.

Это может нормально работать в вашем сценарии , если вы просто измените регистрацию на «оба».Это зависит от объекта и от того, как вы его используете.

При условии, что вы каждый раз используете свежий объект и немедленно удаляете объект, используя Marshall.ReleaseComObject, чтобы у вас не было соблазна повторно использовать его из другого потока, тогда проблем не будет.

(STA означает, что объект может быть вызван только из одного потока. COM гарантирует, что для вас при совместном использовании объектов будет проводиться сортировка между квартирами с различными моделями потоков, поэтому вы можете предполагать, что все объекты в вашей квартиресовместимы с вашей моделью потоков, однако вы также можете предоставить эту гарантию самостоятельно , просто не разделяя объект и не вызывая объект из каких-либо других потоков ).

Для этого просто войдите в реестр под HKEY_CLASSES_ROOT\CLSID\{guid} и измените ключ ThreadingModel на «Оба».

Затем выполните стресс-тестирование.

...