Aracılığıyla paylaş


In-Process Sunucu İş Parçacığı Sorunları

İşlem içi sunucu, CoInitialize, CoInitializeExveya OleInitialize'ı çağırarak iş parçacığı modelini işaretlemez. İş parçacığı kullanan DLL tabanlı veya işlem içi nesneler için, iş parçacığı modelini kayıt defterinde ayarlamanız gerekir. İş parçacığı modeli belirtmediğinizde varsayılan model işlem başına tek iş parçacığıdır. Modeli belirtmek için ThreadingModel değerini kayıt defterindeki InprocServer32 anahtarına eklersiniz.

Sınıf nesnesinin örneğini oluşturmayı destekleyen DLL'ler DllGetClassObjectve DllCanUnloadNowişlevleri uygulamalı ve dışarı aktarmalıdır. İstemci DLL'nin desteklediği sınıfın bir örneğini istediğinde, CoGetClassObject çağrısı (doğrudan veya CoCreateInstanceçağrısı aracılığıyla), nesne DLL'de uygulandığında sınıf nesnesine bir işaretçi almak için DllGetClassObject çağırır. DllGetClassObject bu nedenle birden çok sınıf nesnesi veya tek bir iş parçacığı güvenli nesne verebilmelidir (temelde iç başvuru sayılarında InterlockedIncrement/InterlockedDecrement kullanarak).

Adından da anlaşılacağı gibi, DllCanUnloadNow, onu uygulayan DLL'nin kullanımda olup olmadığını belirlemek için çağrılır ve eğer kullanımda değilse, çağıran tarafından güvenli bir şekilde kaldırılmasını sağlar. Herhangi bir iş parçacığından CoFreeUnusedLibraries çağrıları, her zaman DllCanUnloadNowçağrısını yapmak üzere ana apartmanın iş parçacığı üzerinden yönlendirilir.

Diğer sunucular gibi işlem içi sunucular da tek iş parçacıklı, daire iş parçacıklı veya serbest iş parçacıklı olabilir. Bu sunucular, bu istemci tarafından kullanılan iş parçacığı modelinden bağımsız olarak herhangi bir OLE istemcisi tarafından kullanılabilir.

İstemciler ve işlem içindeki nesneler arasında iş parçacığı modeli birlikte çalışabilirliğinin tüm kombinasyonlarına izin verilir. İstemci ile farklı iş parçacığı oluşturma modelleri kullanan bir işlem içi nesne arasındaki etkileşim, istemciler ve işlem dışı sunucular arasındaki etkileşime tam olarak benzer. İşlem içi bir sunucu için, istemcinin ve işlem içi sunucunun iş parçacığı modeli farklı olduğunda, COM'un kendisini istemciyle nesnesi arasında bir araya alması gerekir.

Tek iş parçacıklı modeli destekleyen bir işlem içi nesne bir istemcinin birden çok iş parçacığı tarafından aynı anda çağrıldığında, COM istemci iş parçacıklarının nesnenin arabirimine doğrudan erişmesine izin veremez."nesne bu tür bir erişim için tasarlanmamıştır. Bunun yerine, COM çağrıların eşitlenmiş olduğundan ve yalnızca nesneyi oluşturan istemci iş parçacığı tarafından yapıldığından emin olmalıdır. Bu nedenle COM, nesneyi istemcinin ana dairesinde oluşturur ve diğer tüm istemci dairelerinin ara sunucuları kullanarak nesneye erişmesini gerektirir.

İstemciye bağlı bir serbest iş parçacıklı daire (çok iş parçacıklı daire modeli) bir apartman iş parçacıklı işlem içi sunucu oluşturduğunda, COM istemcide tek iş parçacıklı bir apartman modeli "konak" iş parçacığını başlatır. Bu ana iş parçacığı, nesneyi oluşturur ve arabirim işaretçisi istemcinin serbest iş parçacıklı birimine aktarılır. Benzer şekilde, bir apartman modeli istemcisindeki tek iş parçacıklı bir daire modeli serbest iş parçacıklı bir işlem içi sunucu oluşturduğunda, COM serbest iş parçacıklı bir konak iş parçacığı (nesnenin oluşturulup ardından istemci tek iş parçacıklı daire modeline geri yönlendirileceği çok iş parçacıklı apartman) oluşturur.

Not

Genel olarak, işlem içi bir sunucuda özel bir arabirim tasarlarsanız, COM'un istemci birimleri arasında arabirimi taşırması için taşıma kodunu da sağlamanız gerekir.

 

COM, tek iş parçacıklı DLL tarafından sağlanan nesnelere, oluşturuldukları istemci daireden erişim gerektirerek erişimin korunmasına yardımcı olur. Buna ek olarak, tüm DLL giriş noktalarına (dllgetclassobjectve DllCanUnloadNowgibi) ve genel verilere her zaman aynı daire tarafından erişilmelidir. COM, istemcinin ana dairesinde bu tür nesneler oluşturur ve ana daireye nesnenin işaretçilerine doğrudan erişim verir. Diğer dairelerden gelen çağrılar, proxy'den ana dairedeki saplamaya ve ardından nesneye gitmek için iş parçacıkları arası marshaling kullanır. Bu, COM'un nesneye çağrıları eşitlemesine olanak tanır. İş parçacığı arası çağrılar yavaş olduğundan, bu sunucuların birden çok daire modelini destekleyecek şekilde yeniden yazılması önerilir.

Tek iş parçacıklı bir işlem içi sunucu gibi, bir apartman modeli DLL'sinin sağladığı nesneye, oluşturulduğu istemci dairesi tarafından erişilmelidir. Ancak, bu sunucu tarafından sağlanan nesneler istemcinin birden çok apartmanında oluşturulabilir, bu nedenle sunucunun çoklu iş parçacıklı kullanım için giriş noktalarını (DllGetClassObject ve DllCanUnloadNow) uygulaması gerekir. Örneğin, bir istemcinin iki dairesi aynı anda işlem içi nesnenin iki örneğini oluşturmaya çalışırsa, DllGetClassObject her iki daire de aynı anda çağrılabilir. DllCanUnloadNow, kod DLL'de yürütülürken DLL'nin yüklenmemesi için yazılmalıdır.

DLL, tüm nesneleri oluşturmak için yalnızca bir sınıf fabrika işlevi örneği sağlıyorsa, birden çok istemci alanı tarafından erişileceği için sınıf fabrika işlevi uygulaması da çok iş parçacıklı kullanım için tasarlanmalıdır. DllGetClassObject her çağrıldığında DLL, sınıf fabrikasının yeni bir örneğini oluşturursa, sınıf fabrikasının iş parçacığı güvenli olması gerekmez.

Sınıf fabrikası tarafından oluşturulan nesnelerin iş parçacığı güvenliğine sahip olması gerekmez. bir iş parçacığı tarafından oluşturulduktan sonra, nesneye her zaman bu iş parçacığı üzerinden erişilir ve nesneye yapılan tüm çağrılar COM tarafından eşitlenir. Bu nesneyi oluşturan istemcinin apartman modeli dairesi, nesneye doğrudan bir işaretçi alır. Nesnenin oluşturulduğu daireden farklı olan istemci daireler proxy'ler aracılığıyla nesneye erişmelidir. Bu proxy'ler, istemci daireleri arasındaki arabirimi sıraladığında oluşturulur.

İşlem içi DLL ThreadingModel değeri "Both" olarak ayarlandığında, bu DLL tarafından sağlanan bir nesne, tek iş parçacıklı veya çok iş parçacıklı istemci çalışma alanlarında doğrudan (proxy olmadan) oluşturulabilir ve kullanılabilir. Ancak, doğrudan yalnızca oluşturulduğu daire içinde kullanılabilir. Nesneyi başka bir daireye vermek için, nesnenin hazırlanması gerekir. DLL nesnesi, kendi senkronizasyonunu uygulamalıdır ve aynı anda birden çok istemci iş parçacığı tarafından erişilebilir.

COM, işlem içi DLL nesnelerine serbest iş parçacıklı erişimin performansını hızlandırmak için CoCreateFreeThreadedMarshaler işlevini sağlar. Bu işlev, işlem içi sunucu nesnesiyle bir arada kullanılabilir bağımsız iş parçacıklı bir yönlendirme nesnesi oluşturur. Aynı işlemdeki bir istemci bölümünün başka bir bölümdeki bir nesneye erişmesi gerektiğinde, serbest iplik dizicisinin toplanması, istemcinin nesnenin arabirimini farklı bir bölüme aktarırken, istemciye bir proxy yerine sunucu nesnesine doğrudan bir işaretçi sağlar. İstemcinin herhangi bir eşitleme yapması gerekmez. Bu yalnızca aynı süreç içinde çalışır; başka bir sürece gönderilen nesneye bir referans için standart marşal etme kullanılır.

Yalnızca serbest iş parçacığını destekleyen bir işlem içi DLL tarafından sağlanan nesne, serbest iş parçacıklı bir nesnedir. Kendi senkronizasyonunu uygular ve aynı anda birden fazla istemci iş parçacığı tarafından erişilebilir. Bu sunucu, iş parçacıkları arasındaki arabirimleri hazırlamaz, bu nedenle bu sunucu doğrudan (proxy olmadan) yalnızca istemcideki çok iş parçacıklı daireler tarafından oluşturulabilir ve kullanılabilir. Bunu oluşturan tek iş parçacıklı daireler buna bir ara sunucu aracılığıyla erişecektir.

Daireler arasında Arabirimlere Erişim

İş Parçacığı Modeli Seçimi

Çok İplikli Uygulamalar

İşlemler, İş Parçacıkları ve Apartmanlar

Single-Threaded ve Çoklu İş Parçacığı İletişimi

Single-Threaded Daireler