STA ve MTA'yı açıklayabilir misiniz?


Yanıtlar:


361

COM iş parçacığı modeli, başlatılan COM nesnelerinin yürütme bağlamının tek bir iş parçacığı (Tek iş parçacığı daire) veya birçok iş parçacığı (çok iş parçacığı daire) ile ilişkili olduğu "daire" modeli olarak adlandırılır. Bu modelde, bir apartman dairesinde başlatıldığında bir COM nesnesi, çalışma süresi boyunca bu dairenin bir parçasıdır.

STA modeli, iş parçacığı için güvenli olmayan COM nesneleri için kullanılır. Bu, kendi senkronizasyonlarını işlemedikleri anlamına gelir. Bunun yaygın bir kullanımı bir UI bileşenidir. Dolayısıyla, başka bir iş parçacığının nesne ile etkileşime girmesi gerekiyorsa (formda bir düğmeye basmak gibi), mesaj STA iş parçacığına sıralanır. Pencereler mesaj pompalama sistemini oluşturur.

COM nesnesi kendi eşitlemesini işleyebiliyorsa, MTA modeli, birden çok iş parçacığının, toplu çağrılar olmadan nesne ile etkileşime girmesine izin verilen yerlerde kullanılabilir.



208

Her şey, nesnelere yapılan çağrıların nasıl ele alındığına ve ne kadar korumaya ihtiyaç duyduklarına bağlı. COM nesneleri, çalışma zamanından aynı anda birden çok iş parçacığı tarafından çağrılmaya karşı korunmalarını isteyebilir; potansiyel olarak farklı evrelerden aynı anda çağrılamayanlar, bu yüzden kendi verilerini korumak zorundalar.

Ayrıca, bir kullanıcı arabirimi iş parçacığından bir arama yapılırsa, çalışma zamanının bir COM nesnesi çağrısının kullanıcı arabirimini engellemesini önlemesi de gerekir.

Bir daire , nesnelerin yaşayacağı bir yerdir ve bir veya daha fazla iş parçacığı içerir. Daire, çağrı yapıldığında ne olacağını tanımlar. Bir apartmandaki nesnelere yapılan çağrılar, zaten doğru dairede bulunan bir evre iş parçacığının kendisi tarafından işlenmesi dışında (yani nesneye doğrudan çağrı) bir istisna olmak üzere, o dairedeki herhangi bir evre üzerinde alınacak ve işlenecektir.

İş parçacıkları, Tek Dişli Daire'de (bu durumda o dairedeki tek iş parçacığıdır) veya Çok Dişli Daire'de olabilir. Hangi iş parçacığı o iş parçacığı için COM başlattığında belirtir.

STA öncelikle belirli bir iş parçacığına bağlı olan kullanıcı arayüzü ile uyumluluk içindir. Bir STA, gizli bir pencereye pencere mesajı alarak işlem çağrılarına ilişkin bildirimler alır; bir giden çağrı yaptığında, diğer pencere mesajlarının işlenmesini önlemek için kalıcı bir mesaj döngüsü başlatır. Uygulamanızın diğer iletilere yanıt verebilmesi için, çağrılacak bir ileti filtresi belirtebilirsiniz.

Bunun aksine, tüm MTA iş parçacıkları işlem için tek bir MTA'yı paylaşır. COM, herhangi bir iş parçacığı yoksa, bir havuz sınırına kadar gelen bir aramayı işlemek için yeni bir çalışan iş parçacığı başlatabilir. Giden çağrılar yapan konular basitçe engellenir.

Basit olması ThreadingModeliçin, sınıflarının anahtarı için değeri ayarlayarak, yalnızca kayıt defterinde desteklediklerini tanıtan DLL'lerde uygulanan nesneleri dikkate alacağız . Dört seçenek vardır:

  • Ana diş ( ThreadingModeldeğer mevcut değil). Nesne, ana bilgisayarın ana UI iş parçacığında oluşturulur ve tüm çağrılar bu iş parçacığına göre sıralanır. Sınıf fabrikası sadece o iş parçacığında çağrılacaktır.
  • Apartment. Bu, sınıfın herhangi bir tek iş parçacıklı mod iş parçacığında çalışabileceğini gösterir. Onu oluşturan iş parçacığı bir STA iş parçacığı ise, nesne bu iş parçacığı üzerinde çalışır, aksi takdirde ana STA'da oluşturulur - ana STA yoksa, bunun için bir STA iş parçacığı oluşturulur. (Bu, Apartment nesneleri oluşturan MTA iş parçacıklarının tüm çağrıları farklı bir iş parçacığına birleştireceği anlamına gelir.) Sınıf fabrikası aynı anda birden çok STA iş parçacığı tarafından çağrılabilir, böylece iç verilerini buna karşı korumalıdır.
  • Free. Bu, MTA'da çalışmak üzere tasarlanmış bir sınıfı belirtir. Bir STA iş parçacığı tarafından oluşturulmuş olsa bile her zaman MTA'ya yüklenir, bu da yine STA iş parçacığının çağrılarının sıralanacağı anlamına gelir. Bunun nedeni, bir Freenesnenin genellikle engelleyebileceği beklentisiyle yazılmasıdır.
  • Both. Bu sınıflar esnektir ve hangi daireden oluşturuldukları yüklenir. Bununla birlikte, her iki gereksinime de uyacak şekilde yazılmalıdır: MTA'ya yüklenmeleri durumunda dahili durumlarını eşzamanlı aramalara karşı korumalı, ancak bir STA'ya yüklenmeleri durumunda engellememelidirler.

.NET Framework'ten, temelde [STAThread]UI oluşturan herhangi bir iş parçacığında kullanın . İşçi iş parçacıkları, Apartmentişaretli COM bileşenlerini kullanmayacakları sürece MTA kullanmalıdır ; bu durumda, aynı bileşen birden çok iş parçacığından çağrılırsa (her iş parçacığının beklemesi gerekeceğinden), ek yükü ve ölçeklenebilirlik sorunlarını önlemek için STA'yı kullanın. bileşen sırayla). Bileşen STA veya MTA'da olsun, iş parçacığı başına ayrı bir COM nesnesi kullanırsanız, her yerde çok daha kolaydır.


Son sonucunuzu beğendim, ancak bununla ilgili olarak, kullanıcı arayüzümde, tek bir gif (yükleyici gibi) bir gif üretmek olan bir UserControl eklemek istersem ne yapmalıyım ... Bu konuda sorun yaşıyorum , gif aynı iş parçacığındaysa dönmüyor ... ve UI'daki MTA'nın harika bir fikir olup olmadığından emin değilim, ne yapardın?
Yogurtu

2
@Yogurtu: Neden COM diş açma modeli hakkında endişeleniyorsunuz? STA / MTA kararı yalnızca kodunuzda COM nesneleri kullanıyorsanız geçerlidir. MTA'yı UI için kullanamazsınız. .NET'in dahili özellikleri bu şekilde kullanılmak üzere tasarlanmamıştır. Animasyonunuz durursa, bunun nedeni kullanıcı arayüzü dizinize mesaj pompalamayı durdurmanızdır. Uzun süren işlemleri bir BackgroundWorker'a taşıyın veya küçük adımlara bölün. Düzgün 60Hz animasyon tutmak için işlerin <16 ms sürmesi gerekiyor!
Mike Dimmick

"Apartman" ve appdomain arasındaki fark nedir?
Puchacz

78

Mevcut açıklamaları da gobbledygook buluyorum. İşte basit İngilizce açıklamam:

STA: Bir iş parçacığı STA olarak ayarlanmış bir COM nesnesi oluşturursa (CoCreateXXX çağrılırken COM nesnesini STA moduna ayarlayan bir bayrak iletebilirsiniz), o zaman yalnızca bu iş parçacığı bu COM nesnesine erişebilir (STA'nın anlamı budur - Tek Dişli Daire ), bu COM nesnesindeki yöntemleri çağırmaya çalışan diğer iş parçacığı, sessizce COM nesnesini oluşturan (sahibi) iş parçacığına iletiler iletmek için kaputun altındadır. Bu, yalnızca bir UI kontrolü oluşturan iş parçacığının doğrudan erişebileceği gerçeğine çok benzer. Ve bu mekanizma karmaşık kilitleme / kilit açma işlemlerini önlemek içindir.

MTA: Bir iş parçacığı MTA olarak ayarlanmış bir COM nesnesi oluşturursa, hemen hemen her iş parçacığı doğrudan yöntemlerini çağırabilir.

Neredeyse özü bu. Teknik olarak, 'STA' paragrafında olduğu gibi bahsetmediğim bazı ayrıntılar olmasına rağmen, içerik oluşturucu iş parçacığının kendisi STA olmalıdır. Ama bu STA / MTA / NA'yı anlamak için bilmeniz gereken her şey.


23

STA (Tek Dişli Daire) temel olarak kodunuzla aynı anda yalnızca bir iş parçacığının etkileşime gireceği konseptidir. Dairenize yapılan çağrılar, Windows mesajları (görünür olmayan bir pencere kullanılarak) ile sıralanır. Bu, çağrıların sıraya alınmasına ve işlemlerin tamamlanmasını beklemesine izin verir.

MTA (Çok Dişli Daire), birçok iş parçacığının aynı anda çalışabileceği ve iş parçacığı güvenliğini işlemek için geliştirici olarak yanınızda.

COM'da diş açma modelleri hakkında daha fazla şey öğrenmek için çok şey var, ancak ne olduklarını anlamada sorun yaşıyorsanız, STA'nın ne olduğunu ve nasıl çalıştığını anlamanın en iyi başlangıç ​​yeri olacağını söyleyebilirim çünkü çoğu COM nesnesi STA'lardır.

Daire İş Parçacıkları, bir iş parçacığı kullandığı nesne ile aynı dairede yaşıyorsa, o zaman bir daire iş parçacığıdır. Bence bu sadece bir COM kavramı çünkü etkileşim kurdukları nesneler ve iş parçacıkları hakkında konuşmanın bir yolu…


19

COM veya OLE denetimlerini barındıran her EXE, daire durumunu tanımlar. Daire durumu varsayılan olarak STA'dır (ve çoğu program için STA olmalıdır).

STA - Zorunlu olarak tüm OLE kontrolleri bir STA'da yaşamalıdır. STA, COM nesnenizin her zaman UI iş parçacığında manipüle edilmesi gerektiği ve diğer iş parçacıklarına (MFC'deki herhangi bir UI öğesi gibi) geçirilemediği anlamına gelir. Ancak, programınızda hala birçok iş parçacığı olabilir.

MTA - COM nesnesini programınızdaki herhangi bir iş parçacığında değiştirebilirsiniz.


13
"STA COM-nesne her zaman UI iş parçacığı üzerinde manipüle edilmesi gerektiği anlamına gelir" Bunun tam olarak doğru olduğunu sanmıyorum ... "UI" iş parçacığı üzerinde olması gerekmez, sadece bir STA iş parçacığı mesaj pompası üzerinde mesajlar kullanarak senkronize çağrılar çünkü. UI iş parçacığı genellikle bu gereksinimleri karşılar, ancak tek olasılık bu değildir.
Brian ONeil

12

Anladığım kadarıyla, 'Daire' COM nesnelerini çoklu iş parçacığı sorunlarından korumak için kullanılır.

Bir COM nesnesi iş parçacığı için güvenli değilse, bunu bir STA nesnesi olarak bildirmelidir. Sonra yalnızca onu oluşturan iş parçacığı erişebilir. Oluşturma iş parçacığı kendisini bir STA iş parçacığı olarak bildirmelidir. Kaputun altında, iş parçacığı STA bilgilerini TLS'de (Yerel Diş Depolama) depolar. Bu davranışı, iş parçacığının bir STA dairesine girmesi olarak adlandırırız. Diğer iş parçacıkları bu COM nesnesine erişmek istediğinde, oluşturma iş parçacığına erişimi marshal gerekir. Temel olarak, oluşturma iş parçacığı bağlı çağrıları işlemek için ileti mekanizması kullanır.

Bir COM nesnesi iş parçacığı için güvenli ise, bunu bir MTA nesnesi olarak bildirmelidir. MTA nesnesine çok iş parçacıklarıyla erişilebilir.


4

COM nesnesi dll'lerini çağıran kod (örneğin, tescilli veri dosyalarını okumak için), bir kullanıcı arabiriminde iyi çalışabilir, ancak gizemli bir şekilde bir hizmetten askıda kalabilir. Bunun nedeni, .NET 2.0 kullanıcı arabirimlerinin STA (iş parçacığı için güvenli) olduğunu varsayarken, hizmetler MTA'yı alır ((bundan önce, hizmet STA olarak kabul edilir).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.