Bisakah Anda menjelaskan STA dan MTA?

391

Bisakah Anda menjelaskan STA dan MTA dengan kata-kata Anda sendiri?

Juga, apa yang dimaksud dengan utas apartemen dan apakah hanya terkait dengan COM? Jika demikian, mengapa?

John
sumber
1
Lihat Juga: Memahami COM Apartments Bagian 1 , Bagian 2
jrh

Jawaban:

361

Model threading COM disebut model "apartemen", di mana konteks eksekusi objek COM yang diinisialisasi terkait dengan salah satu utas (Apartemen Single Thread) atau banyak utas (Apartemen Multi Thread). Dalam model ini, objek COM, setelah diinisialisasi di apartemen, adalah bagian dari apartemen itu selama runtime.

Model STA digunakan untuk objek COM yang tidak aman utas. Itu berarti mereka tidak menangani sinkronisasi mereka sendiri. Penggunaan umum ini adalah komponen UI. Jadi, jika utas lain perlu berinteraksi dengan objek (seperti menekan tombol dalam bentuk), maka pesan tersebut akan dimasukkan ke utas STA. Jendela membentuk sistem pemompaan pesan adalah contohnya.

Jika objek COM dapat menangani sinkronisasi sendiri maka model MTA dapat digunakan di mana beberapa utas diizinkan untuk berinteraksi dengan objek tanpa panggilan yang dibuat.

Joseph Daigle
sumber
1
Bacaan yang bagus untuk perincian lebih lanjut: INFO: Deskripsi dan Cara Kerja Model Threading OLE .
noseratio
208

Semuanya tergantung pada bagaimana panggilan ke objek ditangani, dan seberapa banyak perlindungan yang mereka butuhkan. Objek COM dapat meminta runtime untuk melindunginya agar tidak dipanggil oleh banyak utas secara bersamaan; mereka yang tidak berpotensi dipanggil secara bersamaan dari utas yang berbeda, sehingga mereka harus melindungi data mereka sendiri.

Selain itu, runtime juga diperlukan untuk mencegah panggilan objek COM dari memblokir antarmuka pengguna, jika panggilan dibuat dari utas antarmuka pengguna.

Sebuah apartemen adalah tempat untuk objek untuk hidup, dan mereka mengandung satu atau lebih benang. Apartemen menentukan apa yang terjadi ketika panggilan dilakukan. Panggilan ke objek di apartemen akan diterima dan diproses pada utas apa pun di apartemen itu, dengan pengecualian bahwa panggilan oleh utas yang sudah ada di apartemen yang tepat diproses dengan sendirinya (yaitu panggilan langsung ke objek).

Utas dapat berupa di Apartemen Single-Threaded (dalam hal ini mereka adalah satu-satunya utas di apartemen itu) atau di Apartemen Multi-Threaded. Mereka menentukan kapan utas menginisialisasi COM untuk utas itu.

STA terutama untuk kompatibilitas dengan antarmuka pengguna, yang terkait dengan utas tertentu. STA menerima pemberitahuan panggilan untuk diproses dengan menerima pesan jendela ke jendela tersembunyi; ketika membuat panggilan keluar, ia memulai loop pesan modal untuk mencegah pesan jendela lainnya sedang diproses. Anda dapat menentukan filter pesan yang akan dipanggil, sehingga aplikasi Anda dapat merespons pesan lain.

Sebaliknya semua utas MTA berbagi satu MTA tunggal untuk proses tersebut. COM dapat memulai utas pekerja baru untuk menangani panggilan masuk jika tidak ada utas tersedia, hingga batas kumpulan. Utas membuat panggilan keluar cukup blokir.

Untuk kesederhanaan kami hanya akan mempertimbangkan objek yang diimplementasikan dalam DLL, yang beriklan di registri apa yang mereka dukung, dengan menetapkan ThreadingModelnilai untuk kunci kelas mereka. Ada empat opsi:

  • Utas utama ( ThreadingModelnilai tidak ada). Objek dibuat di utas utama UI host, dan semua panggilan diatur ke utas itu. Pabrik kelas hanya akan dipanggil di utas itu.
  • Apartment. Ini menunjukkan bahwa kelas dapat berjalan pada utas mode-utas tunggal. Jika utas yang membuatnya adalah utas STA, objek akan berjalan pada utas itu, jika tidak maka akan dibuat di STA utama - jika tidak ada STA utama, untaian STA akan dibuat untuknya. (Ini berarti utas MTA yang membuat objek Apartemen akan mengatur semua panggilan ke utas lain.) Pabrik kelas dapat dipanggil bersamaan oleh beberapa utas STA sehingga harus melindungi data internalnya terhadap ini.
  • Free. Ini menunjukkan kelas yang dirancang untuk dijalankan di MTA. Itu akan selalu dimuat di MTA, bahkan jika dibuat oleh utas STA, yang lagi-lagi berarti panggilan utas STA akan di-marshall. Ini karena suatu Freeobjek umumnya ditulis dengan harapan dapat diblokir.
  • Both. Kelas-kelas ini fleksibel dan memuat di apartemen mana pun mereka diciptakan. Mereka harus ditulis agar sesuai dengan kedua set persyaratan, namun: mereka harus melindungi keadaan internal mereka terhadap panggilan bersamaan, jika mereka dimuat di MTA, tetapi tidak boleh memblokir, jika mereka dimuat dalam STA.

Dari .NET Framework, pada dasarnya gunakan saja [STAThread]pada utas apa pun yang membuat UI. Worker threads harus menggunakan MTA, kecuali mereka akan menggunakan Apartmentkomponen COM yang bertanda, dalam hal ini menggunakan STA untuk menghindari masalah overhead dan skalabilitas marshalling jika komponen yang sama dipanggil dari beberapa thread (karena setiap thread harus menunggu untuk komponen pada gilirannya). Lebih mudah di sekitar jika Anda menggunakan objek COM terpisah per utas, apakah komponennya ada di STA atau MTA.

Mike Dimmick
sumber
Saya suka kesimpulan terakhir Anda, tetapi mengenai hal itu, apa yang harus saya lakukan jika saya ingin di UI saya menambahkan UserControl bahwa satu-satunya hal yang dilakukan adalah mereproduksi gif (seperti loader) ... Saya mengalami masalah dengan ini , gif tidak berputar jika mereka berada di utas yang sama ... dan saya tidak yakin jika MTA di UI adalah ide bagus, apa yang akan Anda lakukan?
Yogurtu
2
@Yogurtu: Mengapa Anda khawatir tentang model threading COM sama sekali? Keputusan STA / MTA hanya relevan jika Anda menggunakan objek COM dalam kode Anda. Anda tidak dapat menggunakan MTA untuk UI - .NET internal tidak dimaksudkan untuk digunakan seperti itu. Jika animasi Anda berhenti, itu karena Anda berhenti memompa pesan di utas UI Anda. Pindahkan operasi yang sudah berjalan lama ke BackgroundWorker atau bagi menjadi beberapa langkah kecil. Pekerjaan harus dilakukan <16ms agar animasi 60Hz tetap lancar!
Mike Dimmick
Apa perbedaan antara "apartemen" dan appdomain?
Puchacz
78

Saya menemukan penjelasan yang ada terlalu gobbledygook. Inilah penjelasan saya dalam bahasa Inggris:

STA: Jika utas membuat objek COM yang diatur ke STA (saat memanggil CoCreateXXX, Anda dapat mengoper bendera yang menetapkan objek COM ke mode STA), maka hanya utas ini yang dapat mengakses objek COM ini (itulah yang dimaksud STA - Apartemen Single Threaded) ), utas lain yang mencoba memanggil metode pada objek COM ini ada di bawah kap diam-diam berubah menjadi mengirimkan pesan ke utas yang membuat (memiliki) objek COM. Ini sangat mirip dengan fakta bahwa hanya utas yang membuat kontrol UI yang dapat mengaksesnya secara langsung. Dan mekanisme ini dimaksudkan untuk mencegah operasi kunci / buka yang rumit.

MTA: Jika sebuah utas membuat objek COM yang diatur ke MTA, maka hampir semua utas dapat langsung memanggil metode di atasnya.

Itulah intinya. Meskipun secara teknis ada beberapa detail yang tidak saya sebutkan, seperti pada paragraf 'STA', utas pembuatnya sendiri harus STA. Tapi ini cukup banyak yang harus Anda ketahui untuk memahami STA / MTA / NA.

Weipeng L
sumber
23

STA (Single Threaded Apartment) pada dasarnya adalah konsep bahwa hanya satu utas yang akan berinteraksi dengan kode Anda sekaligus. Panggilan ke apartemen Anda dilakukan melalui pesan windows (menggunakan jendela yang tidak terlihat). Ini memungkinkan panggilan untuk antri dan menunggu operasi selesai.

MTA (Multi Threaded Apartment) adalah tempat di mana banyak utas dapat beroperasi pada saat yang bersamaan dan tanggung jawab ada pada Anda sebagai pengembang untuk menangani keamanan utas.

Ada banyak lagi yang perlu dipelajari tentang model threading dalam COM, tetapi jika Anda kesulitan memahami apa itu model, maka saya akan mengatakan bahwa memahami apa itu STA dan bagaimana cara kerjanya akan menjadi tempat awal terbaik karena sebagian besar objek COM adalah STA.

Apartment Threads, jika sebuah utas tinggal di apartemen yang sama dengan objek yang digunakannya maka itu adalah utas apartemen. Saya pikir ini hanya konsep COM karena ini hanya cara berbicara tentang objek dan utas yang berinteraksi dengan mereka ...

Brian ONeil
sumber
19

Setiap EXE yang menampung kontrol COM atau OLE menentukan status apartemennya. Status apartemen secara default STA (dan untuk sebagian besar program harus STA).

STA - Semua kontrol OLE karena keharusan harus hidup dalam STA. STA berarti objek COM Anda harus selalu dimanipulasi pada utas UI dan tidak dapat dialihkan ke utas lainnya (seperti elemen UI lainnya di MFC). Namun, program Anda masih dapat memiliki banyak utas.

MTA - Anda dapat memanipulasi objek COM pada utas apa pun di program Anda.

Nick
sumber
13
"STA berarti objek COM Anda harus selalu dimanipulasi pada utas UI" Saya tidak berpikir ini benar ... tidak harus pada utas "UI", hanya utas STA yang memiliki pesan pompa di atasnya karena panggilan yang disinkronkan menggunakan pesan. Utas UI biasanya akan memenuhi persyaratan ini, tetapi itu bukan satu-satunya kemungkinan.
Brian ONeil
12

Seperti pemahaman saya, 'Apartemen' digunakan untuk melindungi objek COM dari masalah multi-threading.

Jika objek COM tidak aman thread, itu harus menyatakannya sebagai objek STA. Maka hanya utas yang membuatnya dapat mengaksesnya. Utas penciptaan harus menyatakan dirinya sebagai utas STA. Di bawah tenda, utas menyimpan informasi STA dalam TLS (Utas Penyimpanan Lokal). Kami menyebut perilaku ini karena utas memasuki apartemen STA. Ketika utas lainnya ingin mengakses objek COM ini, ia harus menyusun akses ke utas penciptaan. Pada dasarnya, utas penciptaan menggunakan mekanisme pesan untuk memproses panggilan masuk.

Jika objek COM adalah thread-safe, ia harus mendeklarasikannya sebagai objek MTA. Objek MTA dapat diakses oleh multi-utas.

Kevin C.
sumber
4

Kode yang memanggil objek COM dll (misalnya, untuk membaca file data hak milik), dapat berfungsi dengan baik di antarmuka pengguna tetapi digantung secara misterius dari layanan. Alasannya adalah bahwa pada antarmuka pengguna .Net 2.0 menganggap STA (thread-safe) sementara layanan menganggap MTA ((sebelum itu, layanan diasumsikan STA). Harus membuat thread STA untuk setiap panggilan COM dalam suatu layanan dapat menambah overhead yang signifikan.

pengguna2696845
sumber