Чи можете ви пояснити ДПА та МТА?


391

Чи можете ви пояснити STA та MTA своїми словами?

Крім того, що таке квартирні нитки і чи стосуються вони лише COM? Якщо так, то чому?


1
Дивіться також: Розуміння COM-квартир, частина 1 , частина 2
jrh

Відповіді:


361

Модель різьблення COM називається "квартирною" моделлю, де контекст виконання ініціалізованих об'єктів COM пов'язаний або з однією ниткою (Single Thread Apartment), або з багатьма потоками (Multi Thread Apartment). У цій моделі об’єкт COM, щойно ініціалізований у квартирі, є частиною цієї квартири протягом часу її виконання.

Модель STA використовується для об'єктів COM, які не є безпечними для потоків. Це означає, що вони не обробляють власну синхронізацію. Загальне використання цього компонента - інтерфейс користувача. Отже, якщо інший потік повинен взаємодіяти з об'єктом (наприклад, натисканням кнопки у формі), то повідомлення буде розміщено на потоці STA. Прикладом цього є система перекачування повідомлень Windows.

Якщо об'єкт COM може працювати з власною синхронізацією, то модель MTA може використовуватися там, де дозволено взаємодіяти з об'єктом декількох потоків без маршальованих викликів.


1
Корисне прочитання для отримання детальної інформації: ІНФОРМАЦІЯ: Описи та роботи моделей нитки для нарізування OLE .
nosratio

208

Все зводиться до того, як обробляються дзвінки до об'єктів та який захист їм потрібен. Об'єкти COM можуть запитувати час виконання, щоб захистити їх від виклику кількома потоками одночасно; ті, які не можуть бути викликані одночасно з різних потоків, тому їм доводиться захищати власні дані.

Крім того, також потрібно, щоб час виконання не дозволяв виклику об'єкта COM блокувати користувальницький інтерфейс, якщо виклик здійснюється з потоку користувальницького інтерфейсу.

Квартира є місце для об'єктів , щоб жити, і вони містять один або кілька потоків. Квартира визначає, що відбувається, коли здійснюються дзвінки. Дзвінки на об'єкти в квартирі будуть отримані та оброблені на будь-якій нитці в цій квартирі, за винятком того, що виклик потоком, що вже знаходиться у правій квартирі, обробляється сам (тобто прямий дзвінок на об’єкт).

Нитки можуть бути або в однонитковій квартирі (в такому випадку вони є єдиною ниткою в цій квартирі), або в багатонитковій квартирі. Вони задають, який, коли нитка ініціалізує COM для цього потоку.

STA - це насамперед для сумісності з інтерфейсом користувача, який прив’язаний до конкретної нитки. ДПА отримує сповіщення про дзвінки на обробку, отримуючи віконне повідомлення до прихованого вікна; коли робить вихідний дзвінок, він запускає модальний цикл повідомлень, щоб запобігти обробці інших віконних повідомлень. Ви можете вказати фільтр повідомлень, який потрібно викликати, щоб ваша програма могла відповідати на інші повідомлення.

На противагу цьому всі потоки MTA поділяють одну MTA для цього процесу. COM може запустити новий робочий потік для обробки вхідного дзвінка, якщо немає потоків, до межі пулу. Нитки, що здійснюють вихідні дзвінки, просто блокуються.

Для простоти ми розглянемо лише об’єкти, реалізовані в DLL, які рекламують у реєстрі те, що вони підтримують, встановлюючи ThreadingModelзначення для класу свого класу. Є чотири варіанти:

  • Основна нитка ( ThreadingModelзначення немає) Об'єкт створюється на головному потоці інтерфейсу користувача, і всі виклики перенесені в цей потік. Фабрика класів буде викликана лише на цій темі.
  • Apartment. Це вказує на те, що клас може працювати на будь-якому потоці з однопоточним режимом. Якщо потік, який його створює, є потоком STA, об'єкт буде запускатися на цьому потоці, інакше він буде створений в основній STA - якщо немає основної STA, для нього буде створено нитку STA. (Це означає, що потоки MTA, які створюють об'єкти Квартири, будуть здійснювати зйомки всіх викликів на інший потік.) Фабрику класів можна викликати одночасно кількома потоками STA, тому він повинен захищати свої внутрішні дані від цього.
  • Free. Це вказує на клас, призначений для запуску в MTA. Він завжди завантажується в MTA, навіть якщо він створений потоком STA, що знову означає, що виклики потоку STA будуть скасовані. Це тому, що Freeоб'єкт, як правило, пишеться з очікуванням, що він може блокувати.
  • Both. Ці класи є гнучкими та завантажуються в тій квартирі, з якої вони створені. Вони повинні бути написані таким чином, щоб вони відповідали обом наборам вимог: проте вони повинні захищати свій внутрішній стан від одночасних викликів, якщо вони завантажені в MTA, але не повинні блокувати, якщо вони завантажені в STA.

З .NET Framework в основному просто використовуйте [STAThread]будь-який потік, що створює інтерфейс користувача. Робочі потоки повинні використовувати MTA, за винятком випадків, коли вони будуть використовувати ApartmentCOM-компоненти, позначені COM, і в цьому випадку використовувати STA, щоб уникнути неполадки накладних витрат і масштабованості, якщо один і той же компонент викликається з декількох потоків (оскільки кожен потік повинен буде чекати на компонент по черзі). Навколо набагато простіше, якщо ви використовуєте окремий COM-об'єкт на потік, будь то компонент в STA або MTA.


Мені подобається ваш останній висновок, але щодо цього, що мені робити, якщо я хочу в мій інтерфейс додати UserControl, що єдине, що потрібно зробити - це відтворити gif (наприклад, завантажувач) ... У мене виникають проблеми з цим , gif не крутиться, якщо вони в одній нитці ... і я не впевнений, що MTA в інтерфейсі інтерфейсу - чудова ідея, що б ви зробили?
Йогурту

2
@Yogurtu: Чому ти взагалі турбуєшся про модель різьблення COM? Рішення STA / MTA актуально лише в тому випадку, якщо ви використовуєте об'єкти COM у своєму коді. Ви не можете використовувати MTA для внутрішнього інтерфейсу користувача .NET, таким чином, не призначено. Якщо ваша анімація припиняється, це тому, що ви перестали завантажувати повідомлення на свій потік інтерфейсу. Перемістіть тривалі операції на BackgroundWorker або розділіть на невеликі кроки. Робота повинна тривати <16 мс, щоб зберегти плавну анімацію 60 Гц!
Майк Діммік

Яка різниця між "квартирою" та додатком домену?
Puchacz

78

Я вважаю, що існуючі пояснення є занадто гоблеми. Ось моє пояснення простою англійською мовою:

STA: Якщо потік створює об'єкт COM, встановлений на STA (під час виклику CoCreateXXX ви можете передати прапор, який встановлює об'єкт COM в режим STA), тоді лише ця нитка може отримати доступ до цього об'єкта COM (ось що означає STA - Single Threaded Apartment ), інший потік, який намагається викликати методи цього об'єкта COM, під кришкою мовчки перетворюється на доставку повідомлень до потоку, який створює (володіє) об'єктом COM. Це дуже схоже на те, що тільки потік, який створив елемент управління інтерфейсом, може отримати доступ до нього безпосередньо. І цей механізм покликаний запобігати складним операціям блокування / розблокування.

MTA: Якщо потік створює COM-об'єкт, встановлений на MTA, то майже кожен потік може безпосередньо викликати методи на ньому.

Це в основному суть цього. Хоча технічно є деякі деталі, які я не згадував, як-от в абзаці "STA", потік розробника повинен бути STA. Але це майже все, що ви повинні знати, щоб зрозуміти STA / MTA / NA.


23

STA (Single Threeded Apartment) - це в основному концепція того, що лише один потік одночасно взаємодіє з вашим кодом. Дзвінки у вашу квартиру скасовуються за допомогою вікон повідомлень (використовуючи невидиме) вікно. Це дозволяє чергувати дзвінки і чекати завершення операцій.

MTA (Multi-Threaded Apartment) - це те, що багато потоків можуть працювати одночасно, і навантаження на вас, як розробника, керувати безпекою потоку.

Є багато іншого, щоб дізнатись про нитки моделей в COM, але якщо у вас виникають проблеми з розумінням того, що вони є, я б сказав, що розуміння того, що таке STA та як це працює, було б найкращим місцем для початку, оскільки більшість об'єктів COM - це STA.

Нитка квартири, якщо нитка живе в тій же квартирі, що і об'єкт, який вона використовує, то це квартирна нитка. Я думаю, що це лише концепція COM, оскільки це лише спосіб говорити про об'єкти та теми, з якими вони взаємодіють ...


19

Кожен EXE, у якому розміщені елементи керування COM або OLE, визначає стан квартири. Стан квартири за замовчуванням є STA (і для більшості програм має бути STA).

ДПА - Усі засоби управління OLE за потребою повинні жити в ДПА. STA означає, що вашим COM-об'єктом потрібно завжди керувати потоком інтерфейсу і не може передаватися іншим потокам (подібно до будь-якого елемента інтерфейсу в MFC). Однак у вашій програмі все ще може бути багато потоків.

MTA - Ви можете маніпулювати об'єктом COM на будь-якому потоці програми.


13
"STA означає, що вашим COM-об'єктом потрібно завжди маніпулювати на потоці користувальницького інтерфейсу". Я не думаю, що це абсолютно правильно ... це не повинно бути в потоці "UI", лише нитка STA, яка має повідомлення накачується на ньому, оскільки дзвінки синхронізовані за допомогою повідомлень. Нитка інтерфейсу користувача зазвичай відповідає цим вимогам, але це не єдина можливість.
Брайан ONeil

12

Як я розумію, "Квартира" використовується для захисту об'єктів COM від проблем із багатопотоковою резьбою.

Якщо об'єкт COM не є безпечним для потоків, він повинен оголосити його як об'єкт STA. Тоді до нього може отримати доступ лише нитка, яка її створює. Нитка створення повинна заявляти про себе як потік STA. Під кришкою нитка зберігає інформацію STA у своєму TLS (Thread Local Storage). Ми називаємо цю поведінку такою, що нитка заходить у квартиру ДПА. Коли інші потоки хочуть отримати доступ до цього об'єкта COM, він повинен маршалити доступ до потоку створення. В основному, потік створення використовує механізм повідомлень для обробки вбудованих викликів.

Якщо об'єкт COM захищений потоком, він повинен оголосити його як об'єкт MTA. До об'єкта MTA можна отримати доступ до кількох потоків.


4

Код, який викликає кодові об'єкти COM (наприклад, для читання файлів власних даних), може працювати чудово в користувальницькому інтерфейсі, але загадково висить у сервісі. Причина полягає в тому, що станом на .Net 2.0 користувальницькі інтерфейси приймають STA (безпечно для потоків), а служби передбачають MTA (до цього послуги передбачали STA). Необхідність створення потоку STA для кожного COM-дзвінка в службі може додати значні накладні витрати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.