Yanıtlar:
COM, .NET'in büyük babasıdır. Bununla birlikte oldukça yüksek hedefleri vardı, COM'un yaptığı ancak .NET'in tamamen atladığı şeylerden biri, bir sınıf için iş parçacığı garantileri sağlamaktır. Bir COM sınıfı, ne tür iş parçacığı gereksinimlerine sahip olduğunu yayınlayabilir. COM altyapısı, bu gereksinimlerin karşılanmasını sağlar.
Bu, .NET'te tamamen yoktur. Bir Queue <> nesnesini örneğin birden fazla iş parçacığında kullanabilirsiniz, ancak doğru şekilde kilitlenmezseniz, kodunuzda teşhis edilmesi çok zor olan kötü bir hata olacaktır.
COM iş parçacığının tam ayrıntıları bir gönderiye sığmayacak kadar büyük. Sorunuzun ayrıntılarına odaklanacağım. COM nesnelerini oluşturan bir iş parçacığı, COM'a sınırlı iş parçacığı seçeneklerine sahip COM sınıflarına ne tür bir destek vermek istediğini bildirmelidir. Bu sınıfların büyük çoğunluğu yalnızca sözde Apartman iş parçacığını destekler, arabirim yöntemleri yalnızca örneği oluşturan aynı iş parçacığından güvenli bir şekilde çağrılabilir. Başka bir deyişle, onlar anons "Ben özen lütfen olursa olsun diş desteklemeyen hiçbir zaman yanlış iplikle beni çağırıyor". Hatta müşteri kodu aslında eğer gelmez başka bir iş parçacığı diyoruz.
STA (Tek Dişli Apartman) ve MTA olmak üzere iki çeşidi vardır. COM ile herhangi bir şey yapan herhangi bir iş parçacığı tarafından çağrılması gereken bir işlev olan CoInitializeEx () çağrısında belirtilmiştir. CLR, bir iş parçacığı başlattığında bu aramayı otomatik olarak yapar. Programınızın ana başlangıç iş parçacığı için, Main () yönteminizdeki [STAThread] veya [MTAThread] özniteliğinden geçirilecek değeri alır. Varsayılan, MTA'dır. Kendi oluşturduğunuz iş parçacıkları için SetApartmentState () çağrınız tarafından belirlenir. Varsayılan, MTA'dır. Threadpool konuları her zaman değiştirilemeyen MTA'dır.
Windows'ta STA gerektiren birçok kod var. Kendinizi kullanacağınız dikkate değer örnekler Pano, Sürükle + Bırak ve kabuk diyaloglarıdır (OpenFileDialog gibi). Ve UI Otomasyon programları ve mesajları gözlemlemek için kancalar gibi göremediğiniz birçok kod. Bu kodların hiçbirinin iş parçacığı açısından güvenli olması gerekmez, yazarı, hangi programda kullanıldığını bilmeden onu güvenli hale getirmek için çok zor zamanlar geçirirdi. Buna göre, bir WPF veya Windows Forms projesinin UI iş parçacığı, bir pencere oluşturan herhangi bir iş parçacığı gibi, bu kodu desteklemek için her zaman STA olmalıdır.
Eğer iplik STA Ancak olduğundan COM yapmak söz etmez , tek iplik daire sözleşmesini takip etmek gerekecektir. Oldukça katıdırlar ve sözleşmeyi bozduğunuzda sorunları teşhis etmek zor olabilir. Gereksinimler, herhangi bir süre boyunca iş parçacığını asla engellememeniz ve bir mesaj döngüsü pompalamanızdır. İkinci gereksinim bir WPF veya Winforms 'UI iş parçacığı tarafından karşılanır, ancak kendi STA iş parçacığınızı oluşturuyorsanız, bununla kendiniz ilgilenmeniz gerekecektir. Sözleşmeyi bozmak için ortak teşhis, kilitlenmedir.
Bu gereksinimleri btw desteklemek için CLR'de yerleşik olarak oldukça fazla destek vardır ve bu da beladan uzak durmanıza yardımcı olur. Kilit tablosu ve WaitOne () yöntemleri bir ileti döngüsü pompa zaman bir STA iş parçacığı üzerinde engeller. Bununla birlikte, bu yalnızca hiçbir zaman engelleme gereksinimini karşılar, yine de kendi mesaj döngünüzü oluşturmanız gerekir. Application.Run () hem WPF hem de Winforms.
COM'u mutlu etmek için bir mesaj döngüsüne sahip olmanın önemi hakkında daha fazla ayrıntı içeren bir yanıta daha önce katkıda bulundum. Gönderiyi burada bulacaksınız .