2016-07-21 5 views
0

В MSDN сказан:FreeThreadedDOMDocument, Нейтральная Квартира и свободные Каскадный упаковщик

Если вы пишете однопоточное приложение (или многопоточное приложение, где только один поток обращается к DOM в одно времени), использование прокат модели с резьбой (Msxml2.DOMDocument.3.0 или Msxml2.DOMDocument.6.0). Если вы пишете приложение, в котором доступ к нескольким потокам будет одновременно обращаться к DOM, используйте свободную поточную модель (Msxml2.FreeThreadedDOMDocument.3.0 или Msxml2.FreeThreadedDOMDocument.6.0).

Есть ли связь между FreeThreadedDOMDocument, нейтральными квартирами и маркером с бесплатной резьбой? Я посмотрел в OleView и обнаружил, что модель Threading для FreeThreadedDOMDocument - это Both. Насколько я понимаю, нейтральные квартирные объекты поддерживаются маркером с бесплатной резьбой. Означает ли это, что FreeThreadedDOMDocument не использует марксист с произвольной загрузкой, и он называется немного запутанным как свободно-threaded?

Какова разница между классами COM, отмеченными как свободные, обе или нейтральные? Насколько я понимаю, все они должны быть потокобезопасными, почему разница? Правильно ли, что Neutral должен поддерживать произвольного маршалера?

ответ

1

Здесь есть несколько вопросов.

TL; DR:

нейтральные объекты:

  • ПОНЕСТИ немного меньше в процессе маршалингом чем STA и объект MTA
  • Избегайте нить переключения
  • указатели интерфейса автоматически выстраивали
  • Нейтральная квартира живет до тех пор, пока есть нейтральный объект
  • должен быть готов к run under any kind of thread, используя COM функцию полезности для ожидания или выбора функции Win32 ждать, чтобы использовать в зависимости от типа резьбы

Бесплатных резьбовых объектов:

  • ПОНЕСТИ не практически не в процессе сортировочной
  • Избегайте нить переключения
  • указатели интерфейса не автоматически выстраивали
  • Срок службы привязан к активации квартиры
  • должны быть готовы к run under any kind of thread, используя COM функции полезности для ожидания или выбора функции Win32 ждать, чтобы использовать в зависимости от типа резьбы

Есть ли связь между FreeThreadedDOMDocument, нейтральными квартирами и маркером с бесплатной резьбой?

TL; DR: Модель резьбы FreeThreadedDOMDocument «Both», поэтому она привязана к квартире, где она активирована (создана). Он объединяет бесплатного потокового маршалера, поэтому он является свободным поточным объектом.

FreeThreadedDOMDocument - класс COM, объекты которого объединяют free threaded marshaler. What this marshaler does является предоставление сырой указатель всякий раз, когда выстраивая в процессе (т.е. IMarshal::MarshalInterface с dwDestContext набором для MSHCTX_INPROC.

Я буду использовать определение свободного древовидного объекта как объект, который агрегирует свободный резьбовой маршалинга.

нить, или «Оба» перед Windows 2000, должны быть созданы и использованы в любом потоке, избегая контекстных переключателей.

Если его модель потоковой передачи указана как «Both», , срок службы объекта привязан к квартире, где он был создан. Например, если поток STA завершается , все свободные резьбовые объекты, созданные внутри этой квартиры, либо уничтожаются, либо больше не действуют.

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

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

Означает ли это, что FreeThreadedDOMDocument не использует маркер со свободным потоком, и он называется немного запутанным как свободно-пронумерованный?

Нет, FreeThreadedDOMDocument действительно использует бесплатный нарезной маршалер.

Исторически there were already free threaded objects перед тем Microsoft представил свою собственную поддержку для них (из-за популярности, и, вероятно, потому, что большинство бесплатного резьбового marshalers там были слоеными), а Нейтральная квартира появилась только в Windows 2000.

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

PS: Я упомянул следующую тему в another answer, но я считаю, что контент немного отличается, поскольку вопросы разные.

Вот текущие значения потоковая модель:

  • Нет: использовать главный STA
  • "квартира": использовать любой STA, т.е.если текущая квартира STA или NA над ГНА, использовать текущий STA, в противном случае использовать хост STA (подробнее об этом позже)
  • «Free»: использовать MTA
  • «И»: использовать текущую квартиру
  • «Нейтральная»: использовать Н.А.

Для любой квартиры, которая не существует, COM создает его, если это необходимо.

Есть несколько особенностей здесь:

  • Чтобы использовать главный STA, вы не должны упоминать любую потоковую модель, а не о чем-то более разумном, как «Main»
  • Все имена, кроме «Нейтральная» сделать нет смысла в наше время:
    • «квартира» не чувствует, как ток квартиры, но это не
    • «Free» чувствует, как Fre е резьбовым объекты, но это не
    • «И» заставляет вас думать, есть только 2 типов квартир, но есть 3: STA, MTA и Н. А.
      • На самом деле, так как Windows 8, есть ASTA, изменение ГНО, который создается для GUI, который во время исходящих вызовов, отбрасывает входящие вызовы that are not related, что позволяет избежать большого источника реентерабельности ошибок
      • Вы можете сделать обычный STA вести себя, как это с message filter

Основная STA - первая созданная STA. Это имеет значение только для классов с неуточненной моделью потоков.

Может быть несколько STA, но есть не более одного MTA и одного NA.

Несмотря на то, что активна MTA, любой поток, не инициализированный для COM, неявно находится в MTA, если он не вызывает CoInitializeEx(NULL, COINIT_MULTITHREADED), но он также не влияет на время жизни MTA вообще, то есть MTA может быть уничтожен, поток использует его. Поскольку это почти не документировано и практически ненадежно, вы не должны полагаться на это.

Неявно созданных квартир называются host STA and host MTA. Вы не контролируете их (если только не обманываете CoUninitialize, а в этой квартире, обратите внимание: на самом деле этого не делайте). Фактически, если вы активируете объекты «квартиры» вне STA или вне NA, работающие над STA, они будут активированы в STA хоста. Для дальнейшей путаницы это также может быть основной STA, если первая STA была инициализирована хостом STA.

Все COM-потоки, которые поддерживают хост-квартиры, являются фоновыми потоками, поэтому они не позволяют вашему приложению покидать приложение.

У вас нет никакого контроля над NA, кроме создания его при активации нейтрального объекта. Вы не можете вводить его напрямую, но вы можете создать свой собственный нейтральный объект с помощью метода, который выполняет обратный вызов в контексте нейтральной квартиры. Этот обратный вызов может быть свободным поточным объектом.

Какова разница в реализации между классами COM, которые обозначены как Свободные, Оба или Нейтральные?

COM-классы с квартирой, объявленной как «свободные», приведут к объектам, принадлежащим MTA. Такие объекты могут предполагать, что потоки, которые они запускают, не должны перекачивать сообщения окна. По существу, они могут блокироваться.

Бесплатные резьбовые объекты и нейтральные предметы должны быть подготовлены к run under any apartment. Для бесплатных поточных объектов должно быть очевидно, почему: он обходит любой маршалинг контекста, поэтому методы выполняются в любом потоке. Для нейтральных объектов существует различие which kind of apartment was active (до CoGetApartmentType).

В любом случае, вы должны использовать вспомогательные функции СОМ, как CoWaitForMultipleHandles вместо WaitForMultipleHandles[Ex], который блокирует и является неприемлемым в STA, или MsgWaitForMultipleHandles[Ex], который получает доступ к очереди сообщений окна, вероятно, создавая его неявно, и обычно неприемлемо в MTA.

Вы можете проверить тип квартиры самостоятельно и выбрать подходящие функции ожидания Win32 или использовать стратегию опроса, которая ждет и передает сообщения с тайм-аутами в STA, если вы ожидаете чего-то другого, кроме ручек или если вам нужна определенная логика ожидания.

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

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

При использовании бесплатных резьбовых объектов, входящие и исходящие указатели интерфейсов не выстраивали вообще, то есть либо вы получаете сырые указатели на объекты в той же квартире, или вы получите проксите на объекты в других квартирах. Эти прокси также привязаны к текущей квартире.

Например, входящий необработанный указатель означает, что вы получаете объект, принадлежащий текущей квартире, поэтому вам придется его маршалировать, если вы собираетесь хранить ссылку на объект.

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

Когда бесплатный объект с резьбой должен хранить указатель интерфейса, он всегда должен делать это с помощью ручного маршалинга, и когда он должен вызывать методы из этого указателя интерфейса, он должен сделать это с помощью ручного размаширования.

Обычно Global Interface Table (GIT; другое вводящее в заблуждение название, это фактически in-process table) используется для этой цели.

Насколько я понимаю, все они должны быть потокобезопасными, почему разница?

Что касается безопасности нитей, нет никакой разницы.

Но, как я объяснил в предыдущем вопросе, существует огромная разница при хранении указателей интерфейса и тонкой разницы в отношении активации объекта и времени жизни.

Правильно ли, что Neutral должен поддерживать маркшейдер с бесплатной резьбой?

Беспроблемный маршалер эффективно игнорирует квартиру, поэтому ответственность за поведение, синхронизацию и/или блокировку лежит на методах. Таким образом, ни одна квартира не должна поддерживать бесплатного поточного маршала, это бесплатный объект с резьбой, который должен поддерживать каждую квартиру.

Возможно объединение агрегатора с бесплатной резьбой в объектах с любой моделью резьбы, включая «Нейтраль».

Если вы обнаружите, что настройка контекста нейтральным квартирным маршаллером является каким-то узким местом, то вы можете рассмотреть возможность использования бесплатного потокового маршалера за счет ручного маршалинга хранимых указателей интерфейса. Если нет, просто используйте нейтральную квартиру.

+0

Большое спасибо за такой всеобъемлющий ответ, хотя мне потребуется время, чтобы правильно его переварить :) Как я вижу, это намного сложнее, чем я изначально думал. В любом случае, это дает мне правильные указания, чтобы узнать о теме, и это уже помогло мне понять некоторые вещи. Спасибо! Я проголосовал за него и принял его в качестве ответа. – andrebroz