STAThread ve multithreading


103

STAThread hakkındaki MSDN makalesinden:

Bir uygulama için COM iş parçacığı modelinin tek iş parçacıklı grup (STA) olduğunu gösterir.

(Referans için, makalenin tamamı budur .)

Tek parçacıklı apartman ... Tamam, bu kafamın üzerinden geçti. Ayrıca, uygulamanız COM birlikte çalışmayı kullanmadığı sürece, bu özniteliğin aslında hiçbir şey yapmadığını bir yerde okudum. Peki tam olarak ne işe yarar ve çok iş parçacıklı uygulamaları nasıl etkiler? Çok iş parçacıklı uygulamalar (sadece iş parçacığı Timerhavuzları ve benzerlerini değil, s kullanan herkesten eşzamansız yöntem çağrılarına kadar her şeyi içerir ), 'sadece güvenli olmak için' olsa bile MTAThread kullanmalı mı? STAThread ve MTAThread gerçekte ne yapar?

Yanıtlar:


61

Apartman diş açma bir COM konseptidir; COM kullanmıyorsanız ve aradığınız API'lerin hiçbiri COM "kapakların altında" kullanmıyorsa, apartmanlar için endişelenmenize gerek yoktur.

Dairelerden haberdar olmanız gerekiyorsa, ayrıntılar biraz karmaşık olabilir ; muhtemelen aşırı basitleştirilmiş bir sürüm, STA olarak etiketlenen COM nesnelerinin bir STAThread üzerinde çalıştırılması ve MTA işaretli COM nesnelerinin bir MTA iş parçacığında çalıştırılması gerektiğidir. COM, bu kuralları kullanarak, bu farklı nesneler arasındaki çağrıları, gerekli olmadığı yerlerde sıralamaktan kaçınarak optimize edebilir.


7
Bu aşırı basitleştirilmiş. Çok iş parçacıklı nesneler herhangi bir iş parçacığında çalışabilir. Apartman iş parçacıklı nesneler yalnızca oluşturuldukları dairede çalışabilir.
1800 BİLGİ

28
Bir STA iş parçacığı üzerindeki bir STA nesnesinden bir MTA nesnesine yapılan çağrı, bir MTA iş parçacığına sıralanacaktır (MTA nesnesi serbest iş parçacıklı sıralayıcı uygulamadıkça). Dediğim gibi, detaylar karmaşıklaşabilir. (COM ekibinde birkaç yıl sırıtarak çalıştım )
Bruce

9
Bazen COM'u doğrudan kullanmıyor olsanız bile bunun farkında olmanız gerekir. Bir iş parçacığı, herhangi bir grafik pencere görüntülüyorsa, Tek Parçacıklı Grup modelini kullanmalıdır. Bu nedenle [STAThread], bir Windows form uygulamasında her zaman ana yöntemin en üstünde görüntülenir.
Justin Ethier

6
Siz bilmeden Yazı Tipi veya Dosya iletişim kutusu gibi bir şey COM'u kullanamaz mı? Dahili olarak yaptıklarını varsayıyorum, bu neredeyse tüm Windows Forms uygulamalarının STAThread'in ayarlanmasını gerektireceği anlamına gelmez mi? Aslında COM programlamasını yapmadığım için boş varsayımımı affedin.
Brett Ryan

4
İlgilenenler için daha ayrıntılı bir cevap: stackoverflow.com/questions/4154429/apartmentstate-for-dummies
jgauffin

3

Bu CoInitialize, parametre olarak COINIT_APARTMENTTHREADED belirtilmesinin çağrılmasını sağlar . Herhangi bir COM bileşeni veya ActiveX denetimi kullanmazsanız, bunun size hiçbir etkisi olmayacaktır. Eğer yaparsanız, o zaman bu çok önemlidir.

Apartman iş parçacıklı denetimler etkin tek iş parçacıklıdır, bunlara yapılan çağrılar yalnızca oluşturuldukları apartmanda işlenebilir.

MSDN'den biraz daha ayrıntı:

Tek iş parçacıklı bir grupta (STA) oluşturulan nesneler, yöntem çağrılarını yalnızca kendi apartman iş parçacığından alır, bu nedenle çağrılar serileştirilir ve yalnızca ileti kuyruğu sınırlarına ulaşır (Win32 işlevi PeekMessage veya SendMessage çağrıldığında).

Çok iş parçacıklı bir grupta (MTA) bir COM iş parçacığında oluşturulan nesneler, herhangi bir zamanda diğer iş parçacıklarından yöntem çağrıları alabilmelidir. Nesnenin verilerini korumaya yardımcı olmak için kritik bölümler, semaforlar veya muteksler gibi Win32 senkronizasyon ilkellerini kullanarak çok iş parçacıklı bir nesnenin kodunda genellikle bir tür eşzamanlılık denetimi uygularsınız.

Nötr iş parçacıklı grupta (NTA) çalışacak şekilde yapılandırılmış bir nesne, bir STA veya MTA'daki bir iş parçacığı tarafından çağrıldığında, bu iş parçacığı NTA'ya aktarılır. Bu iş parçacığı daha sonra CoInitializeEx'i çağırırsa, çağrı başarısız olur ve RPC_E_CHANGED_MODE döndürür.


MSDN makalesi, COM açısından yararlıdır, ancak .NET'in / özniteliğine CoInitialize()yanıt olarak ne zaman aradığını söyleyebilir misiniz ? Not: MSDN ile ilgili makale burada: CoInitializeEx işlevi . STAThreadApartmentState
jrh

Does parçacığı> SetApartment kullanmak CoInitialize()içten? STAThread Özniteliğini oraya kadar takip ettim ama iz soğudu (kaynağını bulamıyorum Thread::SetApartment). Thread.h'deki (COM thread.h) Thread sınıfı herhangi bir yerde belgelenmiş mi? MFC, ATL veya başka bir şey mi?
jrh

@jrh Üzgünümden daha fazla ayrıntı bilmiyorum
1800 BİLGİ

-15

STAThread, bir C # GUI Projesinin Ana işlevinden önce yazılır. Hiçbir şey yapmaz, ancak programın tek bir iş parçacığı oluşturmasına izin verir.

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.